了解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重定向”
每一個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幫助我們實現針對某個地址的重定向,其作用與調用HttpResonse的Redirect/RedirectPermanent方法完全一致。如下麵的代碼片斷所示,RedirectResult具有兩個隻讀屬性Permanent和Url,前者表示采用永久重定向還是暫時重定向,默認值為False,後者表示重定向的目標地址,既可以采用絕對地址(比如https://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: }
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重定向”和“301重定向”,302和301表示響應的狀態碼。當我們調用HttpResponse的Redirect/RedirectPermanent方法時,除了會設置相應的響應狀態碼之外,還會將重定向的目標地址寫入響應報頭(Location),瀏覽器在接收到響應之後自動發起針對重定向目標地址的訪問。
1: public class HomeController : Controller
2: {
3: public ActionResult Redirect()
4: {
5: return Redirect("https://www.asp.net");
6: }
7:
8: public ActionResult RedirectPermanent()
9: {
10: return RedirectPermanent("https://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: https://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="https://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: https://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="https://www.asp.net">here</a>.</h2></body></html>
了解ASP.NET MVC幾種ActionResult的本質:EmptyResult & ContentResult
了解ASP.NET MVC幾種ActionResult的本質:FileResult
了解ASP.NET MVC幾種ActionResult的本質:JavaScriptResult & JsonResult
了解ASP.NET MVC幾種ActionResult的本質:HttpStatusCodeResult & RedirectResult/RedirectToRouteResult
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
最後更新:2017-10-25 16:34:07