超高性能的json序列化之MVC中使用Json.Net
先不废话,直接上代码
Asp.net MVC自带Json序列化
1 /// <summary>
2 /// 加载组件列表
3 /// </summary>
4 /// <param name="departmentId">作业部/厂</param>
5 /// <param name="unitId">组件Id</param>
6 /// <param name="tag">标签号</param>
7 /// <param name="pageIndex">当前页码</param>
8 /// <param name="pageSize">每页条数</param>
9 /// <returns>返回组件json数据</returns>
10 public JsonResult ListCom(long departmentId, IEnumberable<long> unitIds, string tag, int pageIndex, int pageSize)
11 {
12 var dataEntity = LdarService.ListCom(unitIds, tag, pageIndex + 1, pageSize);
13 var dataModel = new Page<LdComModel> {Total = dataEntity.Total};
14 var data =
15 dataModel.DataList =
16 dataEntity.DataList.Select(model => Builder.Builder.Convert<LdComModel>(new object[] {model}));
17 dataModel.DataList = data;
18 return Json(new {
19 msg = CommonModelBuilder.BuildQuerySuccessMessage("组件信息维护", (int) dataModel.Total),
20 data = dataModel.DataList,
21 total = dataModel.Total
22 });
23 }
显示到前台界面
请求的报文
LdComModel类中关联了很多外表,也就是导航属性,导航也被序列化,这样不科学,会将所有属性包括导航属性都序列化,还可能会造成循环引用,导致报错。
我只想序列需要的字段,这时可以手写一个匿名类
1 var data=new {
2 model.AreaName,
3 model.AreaId,
4 ......
5 };
这么写字段少还好,字段多就很不爽吧。
这时我们可以用Json.Net序列化,首先引用newtonsoft.json.dll,使用nuget引用比较方便。在不想序列化的属性上打上[JsonIgnore]特性,序列化就会被忽略。
1 /// <summary>
2 /// 分区
3 /// </summary>
4 [JsonIgnore]
5 public LdAreaModel LdAreaModel { get; set; }
6
7 /// <summary>
8 /// 区域名称
9 /// </summary>
10 public string AreaName
11 {
12 get
13 {
14 return LdAreaModel.LdarAreaName;
15 }
16 }
使用JsonNet序列化
1 /// <summary>
2 /// 加载组件列表
3 /// </summary>
4 /// <param name="departmentId">作业部/厂</param>
5 /// <param name="unitId">组件Id</param>
6 /// <param name="tag">标签号</param>
7 /// <param name="pageIndex">当前页码</param>
8 /// <param name="pageSize">每页条数</param>
9 /// <returns>返回组件json数据</returns>
10 public JsonResult ListCom(long departmentId, IEnumberable<long> unitIds, string tag, int pageIndex, int pageSize)
11 {
12 var dataEntity = LdarService.ListCom(unitIds, tag, pageIndex + 1, pageSize);
13 var dataModel = new Page<LdComModel> {Total = dataEntity.Total};
14 var data =
15 dataModel.DataList =
16 dataEntity.DataList.Select(model => Builder.Builder.Convert<LdComModel>(new object[] {model}));
17 dataModel.DataList = data;
18 var result = new JsonNetResult()
19 {
20 Data = new
21 {
22 msg = CommonModelBuilder.BuildQuerySuccessMessage("组件信息维护", (int) dataModel.Total),
23 data = dataModel.DataList,
24 total = dataModel.Total
25 }
26 };
27 return result;
28 }
导航属性没有被序列化,速度也快了很多。
这样写,虽然可以实现功能,很每次都要new一个JsonNetResult对象,写起来很是不爽,能不能给Controller写个扩展方法,像Json(...)一样直接写JsonNet(...)?
Controller中Json(...)方法的部分源码
1 /// <summary>
2 /// 创建一个将指定对象序列化为 JavaScript 对象表示法 (JSON) 的 <see cref="T:System.Web.Mvc.JsonResult"/> 对象。
3 /// </summary>
4 ///
5 /// <returns>
6 /// 将指定对象序列化为 JSON 格式的 JSON 结果对象。在执行此方法所准备的结果对象时,ASP.NET MVC 框架会将该对象写入响应。
7 /// </returns>
8 /// <param name="data">要序列化的 JavaScript 对象图。</param>
9 protected internal JsonResult Json(object data)
10 {
11 return this.Json(data, (string) null, (Encoding) null, JsonRequestBehavior.DenyGet);
12 }
13
14 // <summary>
15 /// 创建 <see cref="T:System.Web.Mvc.JsonResult"/> 对象,该对象使用内容类型、内容编码和 JSON 请求行为将指定对象序列化为 JavaScript 对象表示法 (JSON) 格式。
16 /// </summary>
17 ///
18 /// <returns>
19 /// 将指定对象序列化为 JSON 格式的结果对象。
20 /// </returns>
21 /// <param name="data">要序列化的 JavaScript 对象图。</param><param name="contentType">内容类型(MIME 类型)。</param><param name="contentEncoding">内容编码。</param><param name="behavior">JSON 请求行为</param>
22 protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
23 {
24 return new JsonResult()
25 {
26 Data = data,
27 ContentType = contentType,
28 ContentEncoding = contentEncoding,
29 JsonRequestBehavior = behavior
30 };
31 }
我们可以仿照Controller中的源码,自己给Controller写个扩展方法JsonNet(...)
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Web;
6
7 namespace System.Web.Mvc
8 {
9 public static class ControllerExt
10 {
11 /// <summary>
12 /// 创建一个将指定对象序列化为 JavaScript 对象表示法 (JSON) 的 <see cref="T:System.Web.Mvc.JsonNetResult"/> 对象。
13 /// </summary>
14 ///
15 /// <returns>
16 /// 将指定对象序列化为 JSON 格式的 JSON 结果对象。在执行此方法所准备的结果对象时,ASP.NET MVC 框架会将该对象写入响应。
17 /// </returns>
18 /// <param name="controller">控件器</param>
19 /// <param name="data">要序列化的 JavaScript 对象图。</param>
20 public static JsonNetResult JsonNet(this Controller controller, object data)
21 {
22 return JsonNet(data, (string) null, (Encoding) null, JsonRequestBehavior.DenyGet);
23 }
24
25 /// <summary>
26 /// 创建一个将指定对象序列化为 JavaScript 对象表示法 (JSON) 格式的 <see cref="T:System.Web.Mvc.JsonNetResult"/> 对象。
27 /// </summary>
28 ///
29 /// <returns>
30 /// 将指定对象序列化为 JSON 格式的 JSON 结果对象。
31 /// </returns>
32 /// <param name="controller">控件器</param>
33 /// <param name="data">要序列化的 JavaScript 对象图。</param>
34 /// <param name="contentType">内容类型(MIME 类型)。</param>
35 public static JsonNetResult JsonNet(this Controller controller, object data, string contentType)
36 {
37 return JsonNet(data, contentType, (Encoding) null, JsonRequestBehavior.DenyGet);
38 }
39
40 /// <summary>
41 /// 创建一个将指定对象序列化为 JavaScript 对象表示法 (JSON) 格式的 <see cref="T:System.Web.Mvc.JsonNetResult"/> 对象。
42 /// </summary>
43 ///
44 /// <returns>
45 /// 将指定对象序列化为 JSON 格式的 JSON 结果对象。
46 /// </returns>
47 /// <param name="controller">控件器</param>
48 /// <param name="data">要序列化的 JavaScript 对象图。</param>
49 /// <param name="contentType">内容类型(MIME 类型)。</param>
50 /// <param name="contentEncoding">内容编码。</param>
51 public static JsonNetResult JsonNet(this Controller controller, object data, string contentType,
52 Encoding contentEncoding)
53 {
54 return JsonNet(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet);
55 }
56
57 /// <summary>
58 /// 创建 <see cref="T:System.Web.Mvc.JsonNetResult"/> 对象,该对象使用指定 JSON 请求行为将指定对象序列化为 JavaScript 对象表示法 (JSON) 格式。
59 /// </summary>
60 ///
61 /// <returns>
62 /// 将指定对象序列化为 JSON 格式的结果对象。
63 /// </returns>
64 /// <param name="controller">控件器</param>
65 /// <param name="data">要序列化的 JavaScript 对象图。</param>
66 /// <param name="behavior">JSON 请求行为。</param>
67 public static JsonNetResult JsonNet(this Controller controller, object data, JsonRequestBehavior behavior)
68 {
69 return JsonNet(data, (string) null, (Encoding) null, behavior);
70 }
71
72 /// <summary>
73 /// 创建 <see cref="T:System.Web.Mvc.JsonNetResult"/> 对象,该对象使用指定内容类型和 JSON 请求行为将指定对象序列化为 JavaScript 对象表示法 (JSON) 格式。
74 /// </summary>
75 ///
76 /// <returns>
77 /// 将指定对象序列化为 JSON 格式的结果对象。
78 /// </returns>
79 /// <param name="controller">控件器</param>
80 /// <param name="data">要序列化的 JavaScript 对象图。</param>
81 /// <param name="contentType">内容类型(MIME 类型)。</param>
82 /// <param name="behavior">JSON 请求行为</param>
83 public static JsonNetResult JsonNet(this Controller controller, object data, string contentType,
84 JsonRequestBehavior behavior)
85 {
86 return JsonNet(data, contentType, (Encoding) null, behavior);
87 }
88
89 /// <summary>
90 /// 创建 <see cref="T:System.Web.Mvc.JsonNetResult"/> 对象,该对象使用内容类型、内容编码和 JSON 请求行为将指定对象序列化为 JavaScript 对象表示法 (JSON) 格式。
91 /// </summary>
92 ///
93 /// <returns>
94 /// 将指定对象序列化为 JSON 格式的结果对象。
95 /// </returns>
96 /// <param name="controller">控件器</param>
97 /// <param name="data">要序列化的 JavaScript 对象图。</param>
98 /// <param name="contentType">内容类型(MIME 类型)。</param>
99 /// <param name="contentEncoding">内容编码。</param><param name="behavior">JSON 请求行为</param>
100 public static JsonNetResult JsonNet(this Controller controller, object data, string contentType,
101 Encoding contentEncoding, JsonRequestBehavior behavior)
102 {
103 return JsonNet(data, contentType, contentEncoding, behavior);
104 }
105
106 /// <summary>
107 /// 创建 <see cref="T:System.Web.Mvc.JsonNetResult"/> 对象,该对象使用内容类型、内容编码和 JSON 请求行为将指定对象序列化为 JavaScript 对象表示法 (JSON) 格式。
108 /// </summary>
109 /// <param name="data">要序列化的 JavaScript 对象图。</param>
110 /// <param name="contentType">内容类型(MIME 类型)。</param>
111 /// <param name="contentEncoding">内容编码。</param>
112 /// <param name="behavior"></param>
113 /// <returns>JSON 请求行为</returns>
114 private static JsonNetResult JsonNet(object data, string contentType, Encoding contentEncoding,
115 JsonRequestBehavior behavior)
116 {
117 return new JsonNetResult()
118 {
119 Data = data,
120 ContentType = contentType,
121 ContentEncoding = contentEncoding,
122 JsonRequestBehavior = behavior
123 };
124 }
125
126 }
127 }
写个JsonNetResult类,继承自JsonResult,重写ExecuteResult()方法,内部使用JsonNet来序列化。
1 using System.Text;
2 using Newtonsoft.Json;
3
4 namespace System.Web.Mvc
5 {
6 public class JsonNetResult : JsonResult
7 {
8 public Encoding ContentEncoding { get; set; }
9 public string ContentType { get; set; }
10 public object Data { get; set; }
11
12 public JsonSerializerSettings SerializerSettings { get; set; }
13 public Formatting Formatting { get; set; }
14
15 public JsonNetResult()
16 {
17 SerializerSettings = new JsonSerializerSettings();
18 }
19
20 public override void ExecuteResult(ControllerContext context)
21 {
22 if (context == null)
23 throw new ArgumentNullException("context");
24
25 HttpResponseBase response = context.HttpContext.Response;
26
27 response.ContentType = !string.IsNullOrEmpty(ContentType)
28 ? ContentType
29 : "application/json";
30
31 if (ContentEncoding != null)
32 response.ContentEncoding = ContentEncoding;
33
34 if (Data != null)
35 {
36 var writer = new JsonTextWriter(response.Output) { Formatting = Formatting };
37
38 JsonSerializer serializer = JsonSerializer.Create(SerializerSettings);
39 serializer.Serialize(writer, Data);
40
41 writer.Flush();
42 }
43 }
44 }
45 }
封装后的JsonNet序列化
1 /// <summary>
2 /// 加载组件列表
3 /// </summary>
4 /// <param name="departmentId">作业部/厂</param>
5 /// <param name="unitId">组件Id</param>
6 /// <param name="tag">标签号</param>
7 /// <param name="pageIndex">当前页码</param>
8 /// <param name="pageSize">每页条数</param>
9 /// <returns>返回组件json数据</returns>
10 public JsonNetResult ListCom(long departmentId, IEnumberable<long> unitIds, string tag, int pageIndex, int pageSize)
11 {
12 var dataEntity = LdarService.ListCom(listUnitId, tag, pageIndex + 1, pageSize);
13 var dataModel = new Page<LdComModel> {Total = dataEntity.Total};
14 var data =
15 dataModel.DataList =
16 dataEntity.DataList.Select(model => Builder.Builder.Convert<LdComModel>(new object[] {model}));
17 dataModel.DataList = data;
18 return this.JsonNet(new
19 {
20 msg = CommonModelBuilder.BuildQuerySuccessMessage("组件信息维护", (int) dataModel.Total),
21 data = dataModel.DataList,
22 total = dataModel.Total
23 });
24 }
这样调用起来跟自带的Json(...)一样,非常方便。
由于时间关系,博客就先写到这里。不足及错误之处,敬请批评指正。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。