最近有人問我 ASP.NET MVC 如何實做 HTTP 301 永久轉向 (HTTP 301 Moved Permanently),因為內建的 RedirectResult 或 RedirectActionResult 或 RedirectToRouteResult 的轉向動作都是用 HTTP 302 做轉向,但事實上這個問題與 ASP.NET MVC 無關,因為這部分的解決方法跟 ASP.NET Web Form 一模一樣。
由於 ASP.NET 核心中 HttpResponse 類別的 HttpResponse.Redirect 方法預設就是以 HTTP 302 做轉向,ASP.NET MVC 只是繼續沿用這個方法轉向而已,即便在 ASP.NET Web Form 開發架構下要利用 HTTP 301 轉向一樣要用相同的開發技巧,只要兩行就能夠完成:
Response.StatusCode = 301;
Response.AppendHeader("Location", "/Home/About");
在 ASP.NET MVC 的 Controller 裡由於轉向之後並不需要直接回應 View,所以針對 Action 的回傳值可以有兩種寫法:
1. 使用 Implicit Action Result 將 Action 的回傳型別改成 void
public void Redirect1()
{
Response.StatusCode = 301;
Response.AppendHeader("Location", Url.Action("About"));
}
2. 使用內建的 EmptyResult 回應
public ActionResult Redirect2()
{
Response.StatusCode = 301;
Response.AppendHeader("Location", Url.Action("About"));
return new EmptyResult();
}
當然,如上範例中對於轉向網址的產生我們一律透過 Url Helper 幫我們計算出實際要轉向的網址,這是在 ASP.NET MVC 中的標準作法,因為 ASP.NET 3.5 的 Routing 機制可以讓你輕鬆的定義千變萬化的網址格式。
注意:對於這種不需要回傳 View 的情況,千萬不要利用 Response.End() 中斷 ASP.NET 的執行,因為每當執行 Response.End() 方法都會引發一次 ThreadAbortException 例外狀況,過於頻繁的發生例外狀況會導致系統效能降低、消耗系統資源,對於這種需要轉向而不需要回應 View 的情況,最好利用 EmptyResult 來回應較為恰當。
相關連結