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

问题背景:

           在使用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             else
24             {
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 FormateStr
10         {
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             else
33             {
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 CustomJsonResult
12             {
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 CustomJsonResult
32             {
33                 Data = data,
34                 JsonRequestBehavior = behavior,
35                 FormateStr = format
36             };
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 CustomJsonResult
49             {
50                 Data = data,
51                 FormateStr = format
52             };
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         #endregion
26     }

 

 

posted @ 2013-03-08 19:03  wangyan9110  阅读(19935)  评论(17编辑  收藏  举报