解决Asp.net Mvc返回JsonResult中DateTime类型数据格式的问题

来源:互联网 发布:linux拼音输入法设置 编辑:程序博客网 时间:2024/04/29 18:27

问题背景:

           在使用asp.net mvc 结合jquery esayui做一个系统,但是在使用使用this.json方法直接返回一个json对象,在列表中显示时发现datetime类型的数据在转为字符串是它默认转为Date(84923838332223)的格式,在经过查资料发现使用前端来解决这个问题的方法不少,但是我又发现在使用jquery easyui时,加载列表数据又不能对数据进行拦截,进行数据格式转换之后再加载,后来发现可以通过自定义JsonResult实现,认为这种方法比较可行,就开始研究

我们先来看看jsonResult的源码

 1     public class JsonResult : ActionResult 2     { 3         public JsonResult() 4         { 5             this.JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.DenyGet; 6         } 7          8         public override void ExecuteResult(ControllerContext context) 9         {10             if (context == null)11             {12                 throw new ArgumentNullException("context");13             }14             if ((this.JsonRequestBehavior == System.Web.Mvc.JsonRequestBehavior.DenyGet) && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))15             {16                 throw new InvalidOperationException(MvcResources.JsonRequest_GetNotAllowed);17             }18             HttpResponseBase response = context.HttpContext.Response;19             if (!string.IsNullOrEmpty(this.ContentType))20             {21                 response.ContentType = this.ContentType;22             }23             else24             {25                 response.ContentType = "application/json";26             }27             if (this.ContentEncoding != null)28             {29                 response.ContentEncoding = this.ContentEncoding;30             }31             if (this.Data != null)32             {33                 JavaScriptSerializer serializer = new JavaScriptSerializer();34                 response.Write(serializer.Serialize(this.Data));35             }36         }37         38         public Encoding ContentEncoding { get; set; }39         40         public string ContentType { get; set; }41         42         public object Data { get; set; }43         44         public System.Web.Mvc.JsonRequestBehavior JsonRequestBehavior { get; set; }45     }46 }

当我看到上面代码中的红色部分,我感到有些熟悉,心里比较高兴,以前使用过ashx来传json的都应该用过此方法吧

原来它也是使用这个方法进行序列化的。我们就可以在这个地方先获取到json序列化之后的字符串!然后做写“小动作”,就ok了

下面我就定义了一个自己的JsonResult了

 1     /// <summary> 2     /// 自定义Json视图 3     /// </summary> 4     public class CustomJsonResult:JsonResult 5     { 6         /// <summary> 7         /// 格式化字符串 8         /// </summary> 9         public string FormateStr10         {11             get;12             set;13         }14 15         /// <summary>16         /// 重写执行视图17         /// </summary>18         /// <param name="context">上下文</param>19         public override void ExecuteResult(ControllerContext context)20         {21             if (context == null)22             {23                 throw new ArgumentNullException("context");24             }25 26             HttpResponseBase response = context.HttpContext.Response;27 28             if (string.IsNullOrEmpty(this.ContentType))29             {30                 response.ContentType = this.ContentType;31             }32             else33             {34                 response.ContentType = "application/json";35             }36 37             if (this.ContentEncoding != null)38             {39                 response.ContentEncoding = this.ContentEncoding;40             }41 42             if (this.Data != null)43             {44                 JavaScriptSerializer jss = new JavaScriptSerializer();45                 string jsonString = jss.Serialize(Data);46                 string p = @"\\/Date\((\d+)\)\\/";47                 MatchEvaluator matchEvaluator = new MatchEvaluator(this.ConvertJsonDateToDateString);48                 Regex reg = new Regex(p);49                 jsonString = reg.Replace(jsonString, matchEvaluator);50 51                 response.Write(jsonString);52             }53         }54 55           /// <summary>  56         /// 将Json序列化的时间由/Date(1294499956278)转为字符串 .57         /// </summary>  58         /// <param name="m">正则匹配</param>59         /// <returns>格式化后的字符串</returns>60         private string ConvertJsonDateToDateString(Match m)61         {62             string result = string.Empty;63             DateTime dt = new DateTime(1970, 1, 1);64             dt = dt.AddMilliseconds(long.Parse(m.Groups[1].Value));65             dt = dt.ToLocalTime();66             result = dt.ToString(FormateStr);67             return result;68         }69     }

在这里做的“小动作”就是红色部分,得到字符串以后,通过正则表达式的方式获得Date(12347838383333)的字符串,然后把它转换为DateTime类型,最后在转为我们想要的格式即可,这个格式可以使用FormateStr属性设置。

剩下的就是使用我们自己定义的JsonResult来替换asp.net mvc默认的JsonResult的问题了,接着从源码中找答案,下面是Controller类的部分代码

 1         protected internal JsonResult Json(object data) 2         { 3             return this.Json(data, null, null, JsonRequestBehavior.DenyGet); 4         } 5          6         protected internal JsonResult Json(object data, string contentType) 7         { 8             return this.Json(data, contentType, null, JsonRequestBehavior.DenyGet); 9         }10         11         protected internal JsonResult Json(object data, JsonRequestBehavior behavior)12         {13             return this.Json(data, null, null, behavior);14         }15         16         protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding)17         {18             return this.Json(data, contentType, contentEncoding, JsonRequestBehavior.DenyGet);19         }20         21         protected internal JsonResult Json(object data, string contentType, JsonRequestBehavior behavior)22         {23             return this.Json(data, contentType, null, behavior);24         }25         26         protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)27         {28             return new JsonResult { Data = data, ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior };29         }

以上是Controller类来实例化JsonResult的所有代码。我们只需写一个BaseController类,重写最后一个方法即可,然后我们自己的Controller在继承BaseController即可

下面是BaseController类的部分代码,我们为方便自己个性化的需要又定义了两个MyJosn的方法

 1   /// <summary> 2         /// 返回JsonResult 3         /// </summary> 4         /// <param name="data">数据</param> 5         /// <param name="contentType">内容类型</param> 6         /// <param name="contentEncoding">内容编码</param> 7         /// <param name="behavior">行为</param> 8         /// <returns>JsonReuslt</returns> 9         protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)10         {11             return new CustomJsonResult12             {13                 Data = data,14                 ContentType = contentType,15                 ContentEncoding =contentEncoding,16                 JsonRequestBehavior = behavior,17                 FormateStr = "yyyy-MM-dd HH:mm:ss"18             };19         }20 21         /// <summary>22         /// 返回JsonResult.24         /// </summary>25         /// <param name="data">数据</param>26         /// <param name="behavior">行为</param>27         /// <param name="format">json中dateTime类型的格式</param>28         /// <returns>Json</returns>29         protected JsonResult MyJson(object data, JsonRequestBehavior behavior,string format)30         {31             return new CustomJsonResult32             {33                 Data = data,34                 JsonRequestBehavior = behavior,35                 FormateStr = format36             };37         }38 39         /// <summary>40         /// 返回JsonResult42         /// </summary>43         /// <param name="data">数据</param>44         /// <param name="format">数据格式</param>45         /// <returns>Json</returns>46         protected JsonResult MyJson(object data, string format)47         {48             return new CustomJsonResult49             {50                 Data = data,51                 FormateStr = format52             };53         }

最后我们在自己的Controller中调用即可

 1 public class ProjectMileStoneController : BaseController 2     { 3         /// <summary> 4         /// 首页视图 5         /// </summary> 6         /// <returns>视图</returns> 7         public ActionResult Index() 8         { 9             return this.View();10         }11 12         #region  项目里程碑查询13 14         /// <summary>15         /// 根据项目编号获取项目里程碑16         /// </summary>17         /// <param name="projectId">项目编号</param>18         /// <returns>项目里程碑</returns>19         public JsonResult GetProjectMileStoneByProjectId(int projectId)20         {21             IList<ProjectMileStone> projectMileStones = FacadeContainer.Get<IProjectMileStoneService>().GetProjectMileStonesByProjectId(projectId);22             return this.MyJson(projectMileStones,  "yyyy.MM.dd");23         }24 25         #endregion26     }
0 0
原创粉丝点击