超高性能的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(...)一样,非常方便。

由于时间关系,博客就先写到这里。不足及错误之处,敬请批评指正。

时间: 2024-08-11 21:38:53

超高性能的json序列化之MVC中使用Json.Net的相关文章

使用Json.Net解决MVC中各种json操作

最近收集了几篇文章,用于替换MVC中各种json操作,微软mvc当然用自家的序列化,速度慢不说,还容易出问题,自定义性也太差,比如得特意解决循环引用的问题,比如datetime的序列化格式,比如性能.NewtonSoft.json也就是Json.Net性能虽然不是最好的,但是是比较靠前的,其功能是最强大的,包含各种json操作模式.现在来看看mvc中的替换1, Controller.Json方法这个方法最容易出现循环引用,比如EF查出一个一对多集合想序列化,结果a引用了子表b,b中还引用了a,导

.net和MVC中的json值和List&lt;T&gt;和DataTable的一些转换

1.List<T>集合转换为Json值 List<ReportModel> dtList = new List<ReportModel>(); JsonResult json = new JsonResult(); json = Json(dtList);//直接采用Json()方法就可以了,不过必须要加载MVC 2.DataTable直接转换为Json值,不过必须加载Newtonsoft.dll这个程序集,大家应该在网上找的到. .net和MVC中的json值和Lis

解决MVC Json序列化的循环引用问题/EF Json序列化循引用问题---Newtonsoft.Json

1..Net开源Json序列化工具Newtonsoft.Json中提供了解决序列化的循环引用问题: 方式1:指定Json序列化配置为 ReferenceLoopHandling.Ignore 方式2:指定 JsonIgnore忽略 引用对象 实例1,解决MVC的Json序列化引用方法: step1:在项目上添加引用 Newtonsoft.Json程序包,命令:Insert-Package Newtonsoft.Json step2:在项目中添加一个类,继承JsonResult,代码如下: ///

MVC中处理Json和JS中处理Json对象

事实上,MVC中已经很好的封装了Json,让我们很方便的进行操作,而不像JS中那么复杂了. MVC中: public JsonResult Test() { JsonResult json = new JsonResult { Data = new { Name = "zzl", Sex = "male", } }; return Json(json); }   public JsonResult TestList() { List<User> user

ASP.NET MVC中的Json Binding和Validate

引子:电子商务网站支付功能页面往往会有很多信息,对于这些信息的保存,往往是分步完成的,那么使用Ajax最合适不过了,比如其中的收货人信息模块.这些信息的新建和编辑保存都是用Ajax来完成的.那么有几种方式完成这个操作呢,我想到如下几种. 先来看看该功能的截图: 一般情况下这些信息会对应一个实体类,就命名为:ReceiverInfo,简单起见,我定义ReceiverInfo如下: 1.将需要的值拼接成json文本,再Action里面处理 首先您需要将要保存的值拼接成一个json文本,类似: var

【转】MVC中处理Json和JS中处理Json对象

事实上,MVC中已经很好的封装了Json,让我们很方便的进行操作,而不像JS中那么复杂了. MVC中: public JsonResult Test() { JsonResult json = new JsonResult { Data = new { Name = "zzl", Sex = "male", } }; return Json(json); }   public JsonResult TestList() { List<User> user

IOC容器-Autofac在MVC中实现json方式注入使用

在你阅读时,默认已经了解IOC和autofac的基本用法, 我在最近的我的博客项目中运用了IOC autofac 实现了依赖注入 由于我的项目时asp.net MVC所以我目前向大家展示MVC中如何使用autofac 首先在app_start中新建一个类包含以下方法 using System.Reflection; using Autofac; using Autofac.Integration.Mvc; using System.Web.Mvc; using Microsoft.Extensi

.NET中Json序列化反序列化操作辅助类——基于Json.NET

/// <summary> /// Json操作辅助类 /// </summary> public static class JsonHelper { private static JsonSerializerSettings _jsonSettings; static JsonHelper() { IsoDateTimeConverter datetimeConverter = new IsoDateTimeConverter(); datetimeConverter.DateT

Asp MVC 中处理JSON 日期类型

注:时间有点忙,直接copy 过来的,要查看原址: http://www.developer.com/net/dealing-with-json-dates-in-asp.net-mvc.html Introduction Most of the time, data transfer during Ajax communication is facilitated using JSON format. While JSON format is text based, lightweight a