第五節:從源碼的角度理解各類Result(ActionResult、JsonResult、JavaScriptResult等)

一. 背景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對象而已.有多個重載。

④:應用於下載文件,驗證碼的例子。

相關文章
相關標籤/搜索