了解ASP.NET MVC几种ActionResult的本质:HttpStatusCodeResult & RedirectResult/RedirectToRouteResult
在本系列的最后一篇,我们来讨论最后三个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的更多相关文章
- 了解ASP.NET MVC几种ActionResult的本质:JavaScriptResult & JsonResult
在之前的两篇文章(<EmptyResult & ContentResult>和<FileResult>)我们剖析了EmptyResult.ContentResult和F ...
- 通过源码了解ASP.NET MVC 几种Filter的执行过程 在Winform中菜单动态添加“最近使用文件”
通过源码了解ASP.NET MVC 几种Filter的执行过程 一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神 ...
- ASP.NET MVC几种找不到资源的问题解决办法
转自:http://www.cnblogs.com/xyang/archive/2011/11/24/2262003.html 在MVC中,controller中的Action和View中的.csht ...
- 理解ASP.NET MVC中的ActionResult
通常我们在一个ASP.NET MVC项目中创建一个Controller的时候,Index()方法默认的返回类型都是ActionResult,通过查看UML图,ActionResult实际上是一个抽象类 ...
- 通过源码了解ASP.NET MVC 几种Filter的执行过程
一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神的工作,而且很多人觉得平时根本不需要知道这些,会用就行了.其实阅读源 ...
- ASP.NET MVC 四种传值方法
1.后台传值: public class DataController : Controller { // GET: Data public ActionResult Index() { //1 Vi ...
- ASP.NET MVC 几种 Filter 的执行过程源码解析
一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神的工作,而且很多 人觉得平时根本不需要知道这些,会用就行了.其实阅读 ...
- asp.net mvc 三种过滤器
前几天面试遇到这个问题,发现不是很了解,学习了下,这里记录下来 经常需要将用户的操作记录到日志中,或者是验证用户是否登录了网站, 面对这样的需求,以前的操作是自定义一个统一的全局方法,然后做处理, 在 ...
- ASP.NET MVC 四种Controller向View传值方法
控制器: // Get: Data public ActionResult Index() { //ViewData 方式 ViewData["UserName"] = " ...
随机推荐
- PostgreSQL中的数组与Any
建立表: CREATE TABLE sal_emp ( name text, pay_by_quarter integer[], schedule text[][] ); 插入数据: INSERT I ...
- Apache-系统-网络部分配置
参考了很多东西,但有些理解可能会有错误的地方,希望看到错误的地方可以即使纠正. 参考的内容. http://netsecurity.51cto.com/art/200608/30428.htm htt ...
- linux C(hello world) 解方程
- Android-Chat-Widget
Original: https://github.com/ijarobot/Android-Chat-Widget Backup: https://github.com/eltld/Android-C ...
- Android图片圆角效果
一般来说图片加圆角可以使用 Java 的方式来进行, 对图片略加处理即可, 但也可以使用纯XML+Nice-Patch图片来进行, 这样的速度会更快. 如果背景是纯色的情况下建议使用此方法. 原理则是 ...
- Android横竖屏切换及其相应布局载入问题
第一.横竖屏切换连带载入多屏布局问题: 假设要让软件在横竖屏之间切换.因为横竖屏的高宽会发生转换,有可能会要求不同的布局. 能够通过下面两种方法来切换布局: 1)在res文件夹下建立layout-la ...
- oc-21-class对象
/** 什么是类对象(Class对象)? 类在内存当中也是以对象形式进行存储的. 1.类对象的类型:Class类型 2.如何创建类对象: 1)Class 类对象名 = [类名 class]; 2)类名 ...
- IPC——命名管道
Linux进程间通信——使用命名管道 转载:http://blog.csdn.net/ljianhui/article/details/10202699 在前一篇文章——Linux进程间通信——使用匿 ...
- 项目源码--Android即时通讯IM客户端
下载源码 技术要点: 1.完整精美客户端UI设计 2.自定义控件的灵活使用 3.UI控件的详细使用 4.即时通讯IM协议的实现 5.完整即时通讯IM客户端实现 6.源码详细的中文注释 ……. ...
- Linux清除磁盘上的RAID信息
我的笔记本是DELL的Inspiron 14z,原装存储器是由32G的固态硬盘和512G的机器硬盘组成.后来我自己又给它加了一个256G的固态硬盘,装并装上了CentOS,打算把500G的机械硬盘当资 ...