在本系列的最后一篇,我们来讨论最后三个ActionResult:HttpStatusCodeResult、RedirectResult和RedirectToRouteResult 。第一个用于实现针对某个HTTP状态的响应,而后两个用于实现重定向。至于重定向,又分为“暂时重定向”和“永久重定向”,按照响应状态,又称“302重定向”和“301重定向”。[本文已经同步到《How ASP.NET MVC Works?》中]

目录 一、HttpStatusCodeResult 二、RedirectResult 三、RedirectToRouteResult 四、“302重定向”V.S.“301重定向”

一、HttpStatusCodeResult

每一个HTTP响应均具有一个表示响应状态的代码和一个可选的状态描述,正常情况下返回“200 OK”。System.Web.Mvc.HttpStatusCodeResult使我们很容易地返回一个指定状态的HTTP响应。如下面的代码片断所示,HttpStatusCodeResult具有StatusCode和StatusDescription两个只读的属性分别表示响应状态码和状态描述信息。在构造函数中既可以将状态码设置成一个整数,也可以以HttpStatusCode枚举形式来指定状态码。

   1: public class HttpStatusCodeResult : ActionResult

   2: {    

   3:     public HttpStatusCodeResult(int statusCode);

   4:     public HttpStatusCodeResult(HttpStatusCode statusCode);

   5:     public HttpStatusCodeResult(int statusCode, string statusDescription);

   6:     public HttpStatusCodeResult(HttpStatusCode statusCode, string statusDescription);

   7:  

   8:     public override void ExecuteResult(ControllerContext context);

   9:     

  10:     public int         StatusCode { get; }

  11:     public string      StatusDescription { get;}

  12: }

HttpStatusCodeResult实现在ExecuteResult方法中的请求响应逻辑很简单,如下面的代码片断所示,它仅仅是设置了当前HttpResponse的StatusCode和StatusDescription而已。有一点值得一提的是,如果我们采用Visual Studio的Development Server作为Web应用的宿主,通过HttpStatusCodeResult的StatusDescription属性设置的状态描述信息不会反映HTTP响应中,只有采用IIS作为宿主才会真正将此信息写入响应消息。

   1: public class HttpStatusCodeResult : ActionResult

   2: {

   3:     //其他成员

   4:     public override void ExecuteResult(ControllerContext context)

   5:     {      

   6:         context.HttpContext.Response.StatusCode = this.StatusCode;

   7:         if (this.StatusDescription != null)

   8:         {

   9:             context.HttpContext.Response.StatusDescription = this.StatusDescription;

  10:         }

  11:     }

  12: }

HttpStatusCodeResult具有两个子类,一个基于响应状态“404, Not Found”的System.Web.Mvc.HttpNotFoundResult,另一个是基于响应状态“401, Not Authorized”的System.Web.Mvc.HttpUnauthorizedResult,第7章“Action的执行”中筛选器AuthorizeAttribute在授权检验失败的情况下返回的就是一个HttpUnauthorizedResult对象。

二、RedirectResult

RedirectResult帮助我们实现针对某个地址的重定向,其作用与调用HttpResonse的Redirect/RedirectPermanent方法完全一致。如下面的代码片断所示,RedirectResult具有两个只读属性Permanent和Url,前者表示采用永久重定向还是暂时重定向,默认值为False,后者表示重定向的目标地址,既可以采用绝对地址(比如http://www.asp.net),也可以采用相对地址(比如~/account/register)。

   1: public class RedirectResult : ActionResult

   2: {    

   3:     public RedirectResult(string url);

   4:     public RedirectResult(string url, bool permanent);

   5:     public override void ExecuteResult(ControllerContext context);

   6:   

   7:     public bool       Permanent { get; }

   8:     public string     Url { get; }

   9: }

暂时重定向和永久重定向可以分别通过调用HttpResponse的Redirect和RedirectPermanent来实现,实际上RedirectResult基于重定向的实现就是通过调用这两个方法来完成的,这可以通过如下所示的ExecuteResult方法的定义看出来。

   1: public class RedirectResult : ActionResult

   2: {

   3:     //其他成员

   4:     public override void ExecuteResult(ControllerContext context)

   5:     {

   6:         //其他操作

   7:         string url = UrlHelper.GenerateContentUrl(this.Url, context.HttpContext);

   8:         if (this.Permanent)

   9:         {

  10:             bool endResponse = false;

  11:             context.HttpContext.Response.RedirectPermanent(url, false);

  12:         }

  13:         else

  14:         {

  15:             bool flag2 = false;

  16:             context.HttpContext.Response.Redirect(url, false);

  17:         }

  18:     }

  19: }

三、RedirectToRouteResult

RedirectResult使我们可以直接重定向到指定的目标地址,另一个类似的RedirectToRouteResult帮助我们根据注册的路由进行重定向。如下面的代码片断所示,RedirectToRouteResult没有了表示重定向目标地址的Url属性,取而代之的是表示路由注册名称和路由参数的RouteName和RouteValues属性,在进行重定向时就是根据这两个属性根据注册的路由解析出具体的重定向地址的。

   1: public class RedirectToRouteResult : ActionResult

   2: {   

   3:     public RedirectToRouteResult(RouteValueDictionary routeValues);

   4:     public RedirectToRouteResult(string routeName, RouteValueDictionary routeValues);

   5:     public RedirectToRouteResult(string routeName, RouteValueDictionary routeValues, bool permanent);

   6:     public override void ExecuteResult(ControllerContext context);

   7:    

   8:     public bool                     Permanent { get; }

   9:     public string                   RouteName { get; }

  10:     public RouteValueDictionary     RouteValues { get; }

  11: }

抽象类Controller中定义了一系列创建RedirectResult/RedirectToRouteResult的方法,比如Redirect/RedirectPermanent方法用于创建重定向到指定URL的RedirectResult,RedirectToAction/RedirectToActionPermanent用于创建重定向到指定的目标Action的RedirectResult/RedirectToRouteResult,而RedirectToRoute/RedirectToRoutePermanen创建的RedirectResult/RedirectToRouteResult对象是针对注册的某个路由的。

四、“302重定向”V.S.“301重定向”

暂时重定向和永久重定向有时又被称为“302重定向”和“301重定向”,302和301表示响应的状态码。当我们调用HttpResponse的Redirect/RedirectPermanent方法时,除了会设置相应的响应状态码之外,还会将重定向的目标地址写入响应报头(Location),浏览器在接收到响应之后自动发起针对重定向目标地址的访问。

   1: public class HomeController : Controller

   2: {

   3:     public ActionResult Redirect()

   4:     {

   5:         return Redirect("http://www.asp.net");

   6:     }

   7:  

   8:     public ActionResult RedirectPermanent()

   9:     {

  10:         return RedirectPermanent("http://www.asp.net");

  11:     }

  12: }

在上面的代码片断中,我们定义了采用暂时重定向和永久重定向的Action方法Redirect和RedirectPermanent,如果我们通过浏览器分别对它们发起访访问,会得到具有如下内容的两个响应。两种重定向的不同作用主要体现在SEO(Search engine optimization)上,搜索引擎会使用永久重定向目标地址更新自己的索引,对于暂时重定向则不会。

   1: //1、Redirect

   2: HTTP/1.1 302 Found

   3: Server: ASP.NET Development Server/10.0.0.0

   4: Date: Wed, 13 Jun 2012 09:34:15 GMT

   5: X-AspNet-Version: 4.0.30319

   6: X-AspNetMvc-Version: 4.0

   7: Location: http://www.asp.net

   8: Cache-Control: private

   9: Content-Type: text/html; charset=utf-8

  10: Content-Length: 135

  11: Connection: Close

  12:  

  13: <html><head><title>Object moved</title></head><body><h2>Object moved to <a href="http://www.asp.net">here</a>.</h2></body></html>

  14:  

  15: //2、RedirectPermanent

  16: HTTP/1.1 301 Moved Permanently

  17: Server: ASP.NET Development Server/10.0.0.0

  18: Date: Wed, 13 Jun 2012 09:34:40 GMT

  19: X-AspNet-Version: 4.0.30319

  20: X-AspNetMvc-Version: 4.0

  21: Location: http://www.asp.net

  22: Cache-Control: private

  23: Content-Type: text/html; charset=utf-8

  24: Content-Length: 135

  25: Connection: Close

  26:  

  27: <html><head><title>Object moved</title></head><body><h2>Object moved to <a href="http://www.asp.net">here</a>.</h2></body></html>

了解ASP.NET MVC几种ActionResult的本质:HttpStatusCodeResult & RedirectResult/RedirectToRouteResult的更多相关文章

  1. 了解ASP.NET MVC几种ActionResult的本质:JavaScriptResult & JsonResult

    在之前的两篇文章(<EmptyResult & ContentResult>和<FileResult>)我们剖析了EmptyResult.ContentResult和F ...

  2. 通过源码了解ASP.NET MVC 几种Filter的执行过程 在Winform中菜单动态添加“最近使用文件”

    通过源码了解ASP.NET MVC 几种Filter的执行过程   一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神 ...

  3. ASP.NET MVC几种找不到资源的问题解决办法

    转自:http://www.cnblogs.com/xyang/archive/2011/11/24/2262003.html 在MVC中,controller中的Action和View中的.csht ...

  4. 理解ASP.NET MVC中的ActionResult

    通常我们在一个ASP.NET MVC项目中创建一个Controller的时候,Index()方法默认的返回类型都是ActionResult,通过查看UML图,ActionResult实际上是一个抽象类 ...

  5. 通过源码了解ASP.NET MVC 几种Filter的执行过程

    一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神的工作,而且很多人觉得平时根本不需要知道这些,会用就行了.其实阅读源 ...

  6. ASP.NET MVC 四种传值方法

    1.后台传值: public class DataController : Controller { // GET: Data public ActionResult Index() { //1 Vi ...

  7. ASP.NET MVC 几种 Filter 的执行过程源码解析

    一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神的工作,而且很多 人觉得平时根本不需要知道这些,会用就行了.其实阅读 ...

  8. asp.net mvc 三种过滤器

    前几天面试遇到这个问题,发现不是很了解,学习了下,这里记录下来 经常需要将用户的操作记录到日志中,或者是验证用户是否登录了网站, 面对这样的需求,以前的操作是自定义一个统一的全局方法,然后做处理, 在 ...

  9. ASP.NET MVC 四种Controller向View传值方法

    控制器: // Get: Data public ActionResult Index() { //ViewData 方式 ViewData["UserName"] = " ...

随机推荐

  1. C#获取程序集的版本号和最后编译时间

    C#获取程序集的版本号:string ver = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToStrin ...

  2. 常见错误:Apple Mach-O Linker Error

    常见错误描述: Apple Mach-O Linker Error这类错误的错误信息最后一行通常如下: Command /Developer/Platforms/iPhoneOS.platform/D ...

  3. VCL -- Understanding the Message-Handling System

    Understanding the Message-Handling System http://docwiki.embarcadero.com/RADStudio/XE7/en/Understand ...

  4. 前向否定界定符 python正则表达式不匹配某个字符串 以及无捕获组和命名组(转)

    [编辑] 无捕获组和命名组 精心设计的 REs 也许会用很多组,既可以捕获感兴趣的子串,又可以分组和结构化 RE 本身.在复杂的 REs 里,追踪组号变得困难.有两个功能可以对这个问题有所帮助.它们也 ...

  5. CSS Sprites图片处理

    简介: CSS Sprites是一个网页图片处理方式,在国内都叫CSS精灵,css Sprites允许你将一个页面涉及到的所有零星图片都包含到一张大图中去,这样一来,当访问该页面时,载入的图片就不会像 ...

  6. 内​存​泄​露​调​试​之​ ​v​i​s​u​a​l​ ​l​e​a​k​ ​d​e​t​e​c​t​o​r​ ​工​具【转】

    本文参考此文:http://kangzj.net/visual-leak-detector-download/  另外一种检查内存泄露的工具:visual leak  detector  简称  vl ...

  7. 23+ Useful HTML5 Open Source Online Video Players & Libraries,

    Akamai’s Open Video Player for HTML5 <video> Akamai has released a new Open Video Player for H ...

  8. 用Java实现向Cassandra数据库中插入和查询数据

    所用jar包: 其中jxl.jar和dom4j.jar,jaxen-1.1-beta-6.jar是解析XML文件用的jar包,如果不解析XML文件可以不用. 代码如下: package com.loc ...

  9. 自己编写的.sh脚本文件运行完闪退解决方案

    gnome-terminal设置如下图: 直接原因是,“命令退出时:退出终端”造成的!! 解决方案如下: 1. Ctrl + Alt + F1 ,进入文本操作模式: 2. 登录后,执行:yum ins ...

  10. 终端I/O之规范模式

    规范模式很简单:发一个读请求,输入完一行后,终端驱动程序即刻返回.下列几个条件都会造成读返回: 所要求的字节数已经读到时,读返回.无需读一个完整的行.如果都了部分行,也不会丢失任何信息,下一次读从前一 ...