前言

这一节我们利用上节所讲Unobtrusive Ajax并利用MVC中的JsonResult来返回Json数据。

JsonResult

上节我们利用分部视图返回数据并进行填充,当我们发出请求需要获取数据时都是返回json,所以我们在上一节的基础上进一步学习。

既然是返回Json数据,我们接下来要在控制器上进行定义如下代码:

(1)通过选择的类别名称来筛选数据

private IEnumerable<Blog> GetBlog(string selectedCategory)
{
var data = blogs.AsEnumerable();
if (selectedCategory != "All")
{
Category selected = (Category)Enum.Parse(typeof(Category), selectedCategory);
data = blogs.Where(p => p.Category == selected);
}
return data;
}


(2)利用JsonResult返回Json数据

public JsonResult GetBlogDataJson(string selectedCategory = "All")
{
var data = GetBlog(selectedCategory);
return Json(data, JsonRequestBehavior.AllowGet);
}


(3)接下来我们在视图中利用JS对获取的数据进行拼接

<script type="text/javascript">
function blogData(data) {
var blog = $("#blogsTable");
blog.empty();
for (var i = 0; i < data.length; i++) {
var b = data[i];
blog.append("<tr><td>" + b.ID + "</td><td>"
+ b.Name + "</td><td>" + b.Name + "</td><td>"
+ b.BlogAddress + "</td>" + b.BlogAddress + "<td></td>"
+ b.Description + "</td>" + b.Description + "<td></td>"
+ b.Category + "</td><td>" + b.Category + "</td></tr>");
}
}
</script>


(4)我们通过链接@Url.Action来筛选数据,如下:

@foreach (string category in Enum.GetNames(typeof(Category)))
{
<div class="ajaxLink">
@Ajax.ActionLink(category, "GetBlogs",
new { selectedCategory = category },
new AjaxOptions
{
Url = Url.Action("GetBlogDataJson", new { selectedCategory = category }),
OnSuccess = "blogData" //返回数据后调用上述blogData进行填充数据
})
</div>
}


接下来我们来看看效果:

ASP.NET MVC之JsonResult(六)_序列化

我们点击任意一个类别来看看:

ASP.NET MVC之JsonResult(六)_数据_02

到此为止,我们可以下结论利用JsonResult能够正确返回数据。

但是但是,貌似出了一个问题,你发现了没:类别怎么用数字表示的呢?

分析:我们在通过返回的数据在前台来看看是否是前台返回数据时作了什么手脚。

ASP.NET MVC之JsonResult(六)_序列化_03

到了这里打消了我们上面的推论,看来是后台出问题了,我们想应该在序列化时无法序列化枚举值,于是我们可以做一个测试:

内置JavaScriptSerializer序列化枚举

我们实例化Blog实例:

var blog = new Blog { Id = 4, Name = "xpy0928 4", Category = Category.SQLServer, BlogAddress = "http://www.cnblogs.com/CreateMyself/", Description = "靠自己!" };
var jsonSerial = new JavaScriptSerializer();
var blogJson = jsonSerial.Serialize(blog);
var data = GetBlog(selectedCategory);


序列化如下:

ASP.NET MVC之JsonResult(六)_序列化_04

果然如我们所料,内置序列化无法序列化枚举,此时我们看看枚举中是否有通过其数字得到其名称的方法,查看了一下,需要如下操作:

Enum.GetName(typeof(Category), b.Category)


既然枚举需要进行转换,接着我们通过投影来进行转换,如下:

var data = GetBlog(selectedCategory).Select(b => new
{
ID = b.Id,
Name = b.Name,
BlogAddress = b.BlogAddress,
Description = b.Description,
Category = Enum.GetName(typeof(Category), b.Category)
});
return Json(data, JsonRequestBehavior.AllowGet);


我们再来看看效果:

ASP.NET MVC之JsonResult(六)_json_05 

至此我们对枚举无法进行序列化就这样结束。到这里我想了想,既然序列化类无法进行序列化,那要是Json.Net又会怎样呢?

JSON.NET序列化枚举

var blog = new Blog { Id = 4, Name = "xpy0928 4", Category = Category.SQLServer, BlogAddress = "http://www.cnblogs.com/CreateMyself/", Description = "靠自己!" };
var blogJson = JsonConvert.SerializeObject(blog);


我们看看序列化结果:

ASP.NET MVC之JsonResult(六)_json_06

Json.NET也无法进行序列化枚举,通过查询相关资料,我们在序列化枚举时在枚举类上添加如下特性即可:

[JsonConverter(typeof(StringEnumConverter))]


结语 

之前没怎么接触过序列化过枚举,在学习ASP.NET MVC这一系列时,发现有些东西非常简单,但是在做的过程中,还是或多或少有点小问题,可能别人早已经知道了,但是通过学习今天才明白过来,为时未晚,掌握了就可以了。特此记下:

内置序列化器,序列化枚举通过如下转换

Enum.GetName(typeof(Category), b.Category)


利用JSON.NET序列化枚举

[JsonConverter(typeof(StringEnumConverter))]




你所看到的并非事物本身,而是经过诠释后所赋予的意义