自定义ASP.NET MVC JsonResult序列化结果

本文转自:http://blog.163.com/luckcq@yeah/blog/static/17174770720121293437119/

 

最近项目中前台页面使用EasyUI的jQuery插件开发中遇到,EasyUI Form中的Datebox组件绑定ASP.NET MVC返回的DateTime类型的数据错误,因为ASP.NET MVC返回的DateTime类型的JsonResult的结果中的值是"\/Date(277630788015)\/",于是EasyUI显示的就是返回的值,没有将日期转换,直接显示在DateBox组件中,解决这个问题其实有两种办法:

  1. 扩展EasyUI的datebox组件的parser函数自定义格式化日期格式,不过存在一个问题是如果使用form.load数据是先将值赋给datebox不会调用datebox的parser方法,只有在加载完form后再改变datebox的值为”2011-11-3”格式的值;
  2. 第二种方式就是本文要讲得修改ASP.NET MVC的Json序列化方法,也就是修改JsonResult的序列化方法,下面就来详细说下这种方法。

 

首先看下ASP.NET MVC中的Controller的 Json方法的源码:

        protected internal JsonResult Json(object data) {

            return Json(data, null /* contentType */);

        }

 

        protected internal JsonResult Json(object data, string contentType) {

            return Json(data, contentType, null /* contentEncoding */);

        }

 

        protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding) {

            return new JsonResult {

                Data = data,

                ContentType = contentType,

                ContentEncoding = contentEncoding

            };

        }

可以看出关键还是在JsonResult这个结果类中,JsonResult类的源码如下:

 

    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]

    [AspNetHostingPermission(System.Security.Permissions.SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]

    public class JsonResult : ActionResult {

 

        public Encoding ContentEncoding {

            get;

            set;

        }

 

        public string ContentType {

            get;

            set;

        }

 

        public object Data {

            get;

            set;

        }

 

        public override void ExecuteResult(ControllerContext context) {

            if (context == null) {

                throw new ArgumentNullException("context");

            }

 

            HttpResponseBase response = context.HttpContext.Response;

 

            if (!String.IsNullOrEmpty(ContentType)) {

                response.ContentType = ContentType;

            }

            else {

                response.ContentType = "application/json";

            }

            if (ContentEncoding != null) {

                response.ContentEncoding = ContentEncoding;

            }

            if (Data != null) {

#pragma warning disable 0618

                JavaScriptSerializer serializer = new JavaScriptSerializer();

                response.Write(serializer.Serialize(Data));

#pragma warning restore 0618

            }

        }

    }

}

看到这里大家应该明确我们的修改目标了,对,就是ExecuteResult这个方法,这个方法是序列化Data对象为Json格式的,可见ASP.NET MVC 使用的是System.Web.Script.Serialization.JavaScriptSerializer类

既然明确了目标,那么就开始动手吧。

1. 扩展JsonResult类自定义个CustomJsonResult类,重写ExecuteResult方法代码如下:

    public class CustomJsonResult:JsonResult

    {

        public override void ExecuteResult(ControllerContext context)

        {

            if (context == null)

            {

                throw new ArgumentNullException("context");

            }

 

            HttpResponseBase response = context.HttpContext.Response;

 

            if (!String.IsNullOrEmpty(ContentType))

            {

                response.ContentType = ContentType;

            }

            else

            {

                response.ContentType = "application/json";

            }

            if (ContentEncoding != null)

            {

                response.ContentEncoding = ContentEncoding;

            }

            if (Data != null)

            {

#pragma warning disable 0618

              

                response.Write(JsonConvert.SerializeObject(Data));

#pragma warning restore 0618

            }

        }

我们使用的是Newtonsoft.Json.JsonConvert类序列化对象为Json的,具体集中.NET中的序列化对比可以参考文章:在.NET使用JSON作为数据交换格式

 

  1. 扩展Controller重写Json方法,代码如下:

    public class BaseController:Controller

    {

        protected override JsonResult Json(object data, string contentType, Encoding contentEncoding)

        {

            return new CustomJsonResult

            {

                Data = data,

                ContentType = contentType,

                ContentEncoding = contentEncoding

            };

        }

}

下面就是我们实际使用方法了,因为Newtonsoft.Json.JsonConvert类DateTime类型可以指定序列化日期的类型为: [JsonConverter(typeof(IsoDateTimeConverter))], [JsonConverter(typeof(JavaScriptDateTimeConverter))]

[JsonConverter(typeof(IsoDateTimeConverter))]序列化后的格式为:1981-03-16T00:20:12.1875+08:00

[JsonConverter(typeof(JavaScriptDateTimeConverter))]序列化后的格式为:new Date(-277630787812)

于是我们指定实体类的DateTime属性为IsoDateTimeConverter,代码如下:

 

       [Field("P_Date", "更新日期")]

       [JsonConverter(typeof(IsoDateTimeConverter))]

       public DateTime P_Date { get; set; }

控制器继承自BaseController,Action的返回结果还是JsonResult格式,代码如下:

    public class GoodsController:BaseController

{

        public JsonResult List(string page, string rows)

        {

            Page thepage = new Page() { PageSize = 20, CurrentPage = 1 };

            if (!String.IsNullOrEmpty(rows))

            {

                thepage.PageSize = Convert.ToInt32(rows);

            }

 

            if (!String.IsNullOrEmpty(page))

            {

                thepage.CurrentPage = Convert.ToInt32(page);

            }

            Dictionary<string, object> result = new Dictionary<string, object>();

            result.Add("rows", new BusinessLogic().SelectByPage<GoodsList>(ref thepage));

            result.Add("total", thepage.SumCount);

 

            return Json(result);

        }

}

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。