ASP.NET MVC 404错误处理
ASP.NET MVC 404错误处理
This question already has answers here:
Possible Duplicate:
我已按照Asp.Net MVC(RC 5)中的404 Http错误处理器所述进行了更改,但仍然收到标准的404错误页面。 我需要在IIS中更改些什么吗?
對於如何在MVC(特別是MVC3)中適當地管理404,我進行了很多調查,這是我得出的最佳解決方案:
在global.asax中:
public class MvcApplication : HttpApplication { protected void Application_EndRequest() { if (Context.Response.StatusCode == 404) { Response.Clear(); var rd = new RouteData(); rd.DataTokens["area"] = "AreaName"; // In case controller is in another area rd.Values["controller"] = "Errors"; rd.Values["action"] = "NotFound"; IController c = new ErrorsController(); c.Execute(new RequestContext(new HttpContextWrapper(Context), rd)); } } }
ErrorsController:
public sealed class ErrorsController : Controller { public ActionResult NotFound() { ActionResult result; object model = Request.Url.PathAndQuery; if (!Request.IsAjaxRequest()) result = View(model); else result = PartialView("_NotFound", model); return result; } }
編輯:
如果您使用IoC(例如AutoFac),則應使用以下方式創建控制器:
var rc = new RequestContext(new HttpContextWrapper(Context), rd); var c = ControllerBuilder.Current.GetControllerFactory().CreateController(rc, "Errors"); c.Execute(rc);
而不是
IController c = new ErrorsController(); c.Execute(new RequestContext(new HttpContextWrapper(Context), rd));
(可選)
解釋:
我能想到一個ASP.NET MVC3應用程序可以生成404的6個情況。
由ASP.NET生成:
- 情況1:URL不匹配路由表中的路由。
由ASP.NET MVC生成:
-
情況2:URL匹配路由,但指定的控制器不存在。
-
情況3:URL匹配路由,但指定的動作不存在。
手動生成:
-
情況4:操作使用方法HttpNotFound()返回HttpNotFoundResult。
-
情況5:操作引發HTTPException,狀態代碼為404。
-
情況6:操作手動修改Response.StatusCode屬性為404。
目標
-
(A)向用戶展示自定義的404錯誤頁面。
-
(B)在客戶端響應中保持404狀態代碼(特別是對於SEO非常重要)。
-
(C)直接發送響應,不涉及302重定向。
嘗試的解決方案:自定義錯誤
此解決方案的問題:
- 在場景(1),(4),(6)中不符合目標(A)。
- 不會自動符合目標(B)。必須手動編程。
- 不符合目標(C)。
嘗試的解決方案:HTTP錯誤
此解決方案的問題:
- 僅適用於IIS 7+。
- 在場景(2),(3),(5)中不符合目標(A)。
- 不會自動符合目標(B)。必須手動編程。
嘗試的解決方案:替換HTTP錯誤
此解決方案的問題:
- 僅適用於IIS 7+。
- 不會自動符合目標(B)。必須手動編程。
- 它會遮蔽應用程序級HTTP異常。例如,不能使用customErrors部分,System.Web.Mvc.HandleErrorAttribute等。它只能顯示一般錯誤頁面。
嘗試的解決方案:customErrors和HTTP Errors
和
此解決方案的問題:
- 仅适用于IIS 7+。
- 不符合客观(B)的要求,必须手动编程。
- 在情境(2)、(3)、(5)中不符合客观(C)的要求。
之前遇到过此问题的人甚至尝试创建自己的库(请参见http://aboutcode.net/2011/02/26/handling-not-found-with-asp-net-mvc3.html)。但是前面的解决方案似乎覆盖了所有情况,而不需要使用外部库的复杂度。