一. 背景javascript
提到MVC不得不說MVC中的各類Result,這些高度封裝的xxxResult以及在xxxResult再度封裝的xxx,大大提升了MVC框架的開發效率。前端
相信作過MVC開發的朋友都會用到過 return Content("xx"), 給客戶端的Ajax請求返值,那麼Content內部是怎麼實現的呢?Content和ContentResult之間又是什麼關係呢?ContentResult內部又是怎麼實現的呢?java
與此相似的還有不少:Json方法和JsonResult、JavaScript方法和JavaScriptResult、Empty方法和EmptyResult 等等。ajax
解決上面的問題以前,咱們須要準備兩件利器:mvc
①:ILSpy代碼反射工具(網上下載破解版)。app
②:Reflector Vs的反射插件(經過Nuget下載)。 框架
有了上面這兩種利器中任何一種,就能夠清晰的看到各類Result中的代碼實現了。工具
下面以Content爲例,簡單介紹一下大體思路,在第二模塊,將詳細介紹每一個Result。測試
①:Content方法是返回值爲ContentResult類型的一個方法,即new了一個ContentResult類進行return,代碼以下圖:this
②:ContentResult類內部又是怎麼實現的呢?代碼以下,最後核心代碼是經過 response.write(""),向客戶端返回了一個字符串。
總結:通過這兩步,Content也好,ContentResult也好,原理就很清晰了,下面一樣按照這個套路,詳細的分析各類Result的內部原理,以及測試其使用狀況。
二. 逐個分析
1. ActionResult
①:它是一個抽象類,且包含一個抽象方法ExecuteResult,各類Result都直接或間接繼承ActionResult,並實現ExecuteResult方法。
②:應用於Action方法前面的類型,它是Action的返回值,表明Action的執行結果。
源碼以下:
代碼測試:指向頁面
1 public ActionResult Index() 2 { 3 return View(); 4 }
2. 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中封裝了不少重載。
⑤:應用於action充當APP接口的狀況,且返回Json字符串,但ajax接受到後,會自動轉換成Json對象進行使用。
源碼以下:
代碼測試:
1 /// <summary> 2 /// 經過Index1頁面向該方法發送請求 3 /// 前端拿到的是JSON字符串,須要前端轉換 4 /// </summary> 5 /// <returns></returns> 6 public ActionResult GetInfor() 7 { 8 var data =new 9 { 10 id="1", 11 name="mr" 12 }; 13 string data2 = new JavaScriptSerializer().Serialize(data); 14 return Json(data2, JsonRequestBehavior.AllowGet); 15 } 16 /// <summary> 17 /// 前端拿到的是JSON對象,前端能夠直接調用 18 /// </summary> 19 /// <returns></returns> 20 public ActionResult GetInfor2() 21 { 22 var data = new 23 { 24 id = "1", 25 name = "mr" 26 }; 27 return Json(data, JsonRequestBehavior.AllowGet); 28 }
測試結果:一個返回了Json對象,一個返回了Json字符串
3. JavaScriptResult
①:繼承了ActionResult,實現了ExecuteResult方法。
②:解讀源碼可知:JavaScriptResult內部實現原理,設置了返回參數類型 response.ContentType = "application/x-javascript";
而後經過: response.Write(this.Script);將js代碼返回前臺。
能夠觸類旁通:經過ContentResult而且設置其類型爲"application/x-javascript",能夠達到ContentResult一樣的效果。
③:在MVC的Action中,return JavaScript(),這裏的JavaScript經過源碼可知,即new了一個JavaScriptResult對象而已,而且MVC中封裝了不少重載。
④:應用於經過後臺返給前端js代碼。
源碼以下:
代碼測試:下面兩段代碼的結果是一致的
1 public ActionResult GetJs() 2 { 3 return JavaScript("alert('我是js代碼,調用的是JavaScriptResult')"); 4 } 5 public ActionResult GetJs2() 6 { 7 return Content("alert('我是js代碼,調用的是ContentResult,並自定義的返回類型爲js')", "application/x-javascript"); 8 }
4. ContentResult
①:繼承了ActionResult,實現了ExecuteResult方法。
②:解讀源碼可知,ContentResult內部實現原理直接將數據經過這個方法Response.Write(string s)直接返回。
③:在MVC的Action中,return Content(),這裏的Content經過源碼可知,即new了一個ContentResult對象而已,而且MVC中封裝了不少重載,能夠手動設置的返回類型。
④:應用於返回一個簡單的判斷字段,默認表示一個文本內容,以下面的例子。
代碼測試:下面兩段代碼效果原理是一致的。
1 /// <summary> 2 /// 下面這兩種狀況達到的效果是一致的,原理也一致 3 /// </summary> 4 public void GetInfor3() 5 { 6 Response.Write("ok"); 7 } 8 public ActionResult GetInfor4() 9 { 10 return Content("ok"); 11 }
5. EmptyResult
①:繼承了ActionResult,實現了ExecuteResult方法。
②:解讀源碼可知:EmptyResult內部實現原理,實際上它的ExecuteResult方法中爲空,什麼也沒有。
③:在MVC的Action中,return Empty(),這裏的Empty經過源碼可知,即new了一個EmptyResult對象而已,而且MVC中封裝了不少重載。
④:這裏的EmptyResult起到一個適配器做用,一箇中轉的做用,能夠應用於請求不須要顯示頁面的狀況。
6. RedirectResult
①:繼承了ActionResult,實現了ExecuteResult方法。
②:解讀源碼可知:RedirctResult內部實現原理,實際上它的ExecuteResult方法調用的是context.HttpContext.Response.Redirect(text, false)。
③:在MVC的Action中,return Redirct(),這裏的Redirct經過源碼可知,即new了一個RedirctResult對象而已。
④:應用於在後臺進行跨站點跳轉和同站點間action之間進行跳轉。
源碼以下:
代碼測試:同站點和跨站點間的跳轉。
1 /// <summary> 2 /// 跨站點跳轉 3 /// </summary> 4 /// <returns></returns> 5 public ActionResult RedirctToBaidu() 6 { 7 return Redirect("http://www.baidu.com"); 8 } 9 /// <summary> 10 /// 同站點間action之間進行跳轉 11 /// </summary> 12 /// <returns></returns> 13 public ActionResult RedictOtherAction() 14 { 15 return Redirect("/Third/GetInfor4"); 16 }
7. RedirectToRouteResult
①:也是與頁面跳轉相關的。
②:mvc中 return RedirectToAction(""); return RedirectToRoute();都是跳轉的一些變種,這裏再也不詳細分析了。
8. FileResult
①:繼承了ActionResult,實現了ExecuteResult方法。
②:解讀源碼可知:FileResult 內部實現原理,實際上它的ExecuteResult方法調用的是WriteFile(response)。
③:MVC的Action中,return File(),即new了一個FileResult對象而已.有多個重載。
④:應用於下載文件,驗證碼的例子。