1. 程式人生 > >解決Asp.net Mvc返回JsonResult中DateTime型別資料格式的問題

解決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     }