日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

第三节:框架前期准备篇之利用Newtonsoft.Json改造MVC默认的JsonResult

發布時間:2023/12/10 c/c++ 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第三节:框架前期准备篇之利用Newtonsoft.Json改造MVC默认的JsonResult 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一. 背景

  在MVC框架中,我們可能經常會用到 return Json(),而Json方法內部又是一個JsonResult類,那么JsonResult內部又是什么原理呢?在MVC框架中,各種xxxResult便捷了我們的開發,但這些都不是本節的重點,在這里我們只需要知道JsonResult內部的原理即可。

  JsonResult內部原理是基于 JavaScriptSerializer來做的序列化,在使用過程中,有這么幾個弊端:

  ①:DateTime類型返回給前端格式不友好:\/Date(1535009968228)\/ ,相當別扭。(PS:前端有很多辦法處理的)

  ②:對于前端而言,對于屬性名可能更傾向于小寫開頭,但在C#中,很多都是大寫,但JsonResult將原結果默認返回給前端,前端人員可能會有點小不爽。(PS:這也可以算作是一個習慣問題,沒有明確的對錯)

  ③:循環引用的問題。

? 關于使用Newtonsoft.Json改造MVC默認的JsonResult,有很多種方式,本節僅是整理了一下在我日常開發中的使用方法。(PS:這里的MVC版本為:?5.2.4.0)

?  這里簡單的分析一下JsonResult的源碼:

?①:繼承了ActionResult, 實現了ExecuteResult方法。

?②:解讀源碼可知,JsonResult內部實現原理是調用了JavaScriptSerializer對象中的Serialize方法,將Json對象轉換成了Json字符串,通過:response.Write(javaScriptSerializer.Serialize(this.Data)); 傳遞給前臺。

?③:默認是禁止Get請求訪問的. JsonRequestBehavior.DenyGet。

?④:在MVC的Action中,return Json(),這里的Json通過源碼可知,即new了一個JsonResult對象而已,并且MVC中封裝了很多重載。

?

  本節涉及到的知識點有:

    1. MVC中的各種Result,可參考:http://www.cnblogs.com/yaopengfei/p/7910767.html

    2. MVC中的過濾器,可參考:https://www.cnblogs.com/yaopengfei/p/7910763.html

二. 測試JsonResult的弊端

?  這里主要測試一下DateTime類型“亂碼”(時間戳)問題和默認大小寫問題。

后臺代碼:

1 public ActionResult Json1()2 {3 var msg = new4 {5 ID = 1,6 Name = "ypf1",7 time = DateTime.Now8 };9 return Json(msg); 10 }

前臺代碼:

1 $("#btn1").on("click", function () { 2 $.post("Json1", {}, function (data) { 3 console.log(data); 4 }); 5 });

測試結果:

?

下面提供一種解決時間戳轉換的問題,使用該js文件,對Date類型進行擴展,代碼如下:

?View Code

在前端這么使用,就可以將時間轉換成正常的顯示:(詳細的見上面的代碼)

?

三. 自我改造

?  有了前面的JsonResult的代碼分析,這里先寫一種最簡單粗暴的改造方式,當然需要實現安裝 Newtonsoft.Json程序集。

改造方案一:

?  新建YpfSimpleJsonResult類,繼承ActionResult類,利用構造函數傳遞數據,override ExecuteResult方法,在里面利用Newtonsoft進行改寫,代碼如下:

1 /// <summary>2 /// 簡潔版的改寫,只是替換了實現方式3 /// </summary>4 public class YpfSimpleJsonResult : ActionResult5 {6 private object _Data = null;7 public YpfSimpleJsonResult(object data)8 {9 this._Data = data; 10 } 11 public override void ExecuteResult(ControllerContext context) 12 { 13 context.HttpContext.Response.ContentType = "application/json"; 14 context.HttpContext.Response.Write(JsonConvert.SerializeObject(this._Data)); 15 } 16 }

測試接口:

1 public ActionResult Json3()2 {3 var msg = new4 {5 ID = 1,6 Name = "ypf1",7 time = DateTime.Now8 };9 return new YpfSimpleJsonResult(msg); 10 }

測試結果:

?

改造方案二:

  有了上面的方案的基礎,下面深度改造一下,新建YpfJsonResult類,直接繼承高層封裝JsonResult類,并配置引用問題、默認小寫問題、自定義時間格式,代碼如下:

1 public class YpfJsonResult : JsonResult2 {3 public YpfJsonResult()4 {5 Settings = new JsonSerializerSettings6 {7 //1. 忽略循環引用問題,建議設置為Error,這樣的話遇到循環引用的時候報錯8 ReferenceLoopHandling = ReferenceLoopHandling.Ignore,9 //2. 日期格式化,這里可以將Newtonsoft默認的格式進行修改 10 DateFormatString = "yyyy-MM-dd HH:mm:ss", 11 //3. 設置屬性為開頭字母小寫的駝峰命名 12 ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() 13 }; 14 } 15 16 public JsonSerializerSettings Settings { get; private set; } 17 18 public override void ExecuteResult(ControllerContext context) 19 { 20 if (context == null) 21 { 22 throw new ArgumentNullException("context"); 23 } 24 if (this.JsonRequestBehavior == JsonRequestBehavior.DenyGet && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) 25 { 26 throw new InvalidOperationException("GET is not allowed"); 27 } 28 HttpResponseBase response = context.HttpContext.Response; 29 response.ContentType = string.IsNullOrEmpty(this.ContentType) ? "application/json" : this.ContentType; 30 if (this.ContentEncoding != null) 31 { 32 response.ContentEncoding = this.ContentEncoding; 33 } 34 if (this.Data == null) 35 { 36 return; 37 } 38 var scriptSerializer = JsonSerializer.Create(this.Settings); 39 scriptSerializer.Serialize(response.Output, this.Data); 40 } 41 }

測試接口:

1 public ActionResult Json2()2 {3 var msg = new4 {5 ID = 1,6 Name = "ypf1",7 time = DateTime.Now8 };9 //注意:這里的Data是JsonResult類中的一個獲取和設置數據的屬性。 10 return new YpfJsonResult() { Data = msg }; 11 }

測試結果:

總結:

?  雖然我們通過第二套方案已經達到了我們的目的,但它存在一個弊端,就是侵入性太強,每個方法中都要改寫,那么有沒有一種方式可以全局控制呢?

  顯然是有的,可以考慮使用全局過濾器。

?

四. 全局處理

?  這里換一種思路,通過注冊一個全局過濾器,對每個Action進行監測,如果使用的是JsonResult,就把JsonResult替換成自己編寫的YpfJsonResult,這樣的話業務中的調用代碼,不需要發生任何變化,仍然可以使用 return Json()方法。

  特別注意:這里的過濾器要使用行為過濾器,并且要在OnActionExecuted方法中進行業務的編寫。(這是過濾器執行順序決定的)

代碼分享:

?過濾器代碼

編寫完過濾器后,需要全局注冊一下:

  可以在在FilterConfig文件中注冊 filters.Add(new YpfJsonFilter());

  或者直接去:Global文件中:GlobalFilters.Filters.Add(new YpfJsonFilter()); 代碼來注冊,道理都一樣

接口代碼,不需要做任何改變,繼續沿用return Json()即可。

測試結果:

?

?

?

?

?

?

!

  • 作???????者 :?Yaopengfei(姚鵬飛)
  • 博客地址 :?http://www.cnblogs.com/yaopengfei/
  • 聲?????明1 : 本人才疏學淺,用郭德綱的話說“我是一個小學生”,如有錯誤,歡迎討論,請勿謾罵^_^。
  • 聲?????明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。

總結

以上是生活随笔為你收集整理的第三节:框架前期准备篇之利用Newtonsoft.Json改造MVC默认的JsonResult的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。