第五节:从源码的角度理解各类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对象而已.有多个重载。

④:应用于下载文件,验证码的例子。

相关文章
相关标签/搜索