在本系列的最后一篇,我们来讨论最后三个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# 图片裁剪代码

    /// <summary> /// 缩小裁剪图片 /// </summary> /// <param name="int_Width">要缩小裁 ...

  2. android中判断sim卡状态和读取联系人资料的方法

    在写程序中,有时候可能需要获取sim卡中的一些联系人资料.在获取sim卡联系人前,我们一般会先判断sim卡状态,找到sim卡后再获取它的资料,如下代码我们可以读取sim卡中的联系人的一些信息. Pho ...

  3. apache2.2 虚拟主机配置

    一.改动httpd.conf 打开appserv的安装文件夹,找到httpd.conf文件,分别去掉以下两行文字前面的#号. #LoadModule vhost_alias_module module ...

  4. plupload上传插件在SpringMVC中的整合

    前言:近期在给学院的站点做一个加入附件的功能,首先到了某某邮箱看了一下.简单有用.可是是flash做的,无法拷贝.就仅仅好上网找插件了.经过筛选.最终找到plupload这款插件(其实有的编辑器自带加 ...

  5. 20 Free Open Source Web Media Player Apps

    free Media Players (Free MP3, Video, and Music Player ...) are cool because they let web developers ...

  6. oc-15-枚举结构体

    Cat.h #import <Foundation/Foundation.h> // 颜色的枚举 typedef enum{ ColorBlack, ColorYeallow } Colo ...

  7. springMVC与struts2的区别

    1. 机制:spring mvc的入口是servlet,而struts2是filter,这样就导致了二者的机制不同. 2. 性能:spring会稍微比struts快.spring mvc是基于方法的设 ...

  8. 学了这四招,你在Linux上观看Netflix视频不发愁

    导读 一份崭新的Linux发行版已经安装到你的电脑上,你完全准备好使用免费开源办公软件处理长时间的工作.但是你可能会问自己:"难道除了工作,就没有乐趣可言?我就是想观看Netflix视频!& ...

  9. Quartz 设置一个半小时任务实现

    该文章属于本人原创,转载请注明出处.   spring + Quartz 设置定时任务时要求没一个半小时执行一次   设置两个相同的定时任务   第一个从整点开始每三小时执行一次           ...

  10. C# 之 user32函数库

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.R ...