今天在處理mvc 項目404和500頁面時,發現我以前比較喜歡用的Return HttpNotFound()沒有跳轉到我在webconfig中配置的自定義404頁面,而且也不會去執行Global中的Application_Error方法,經過一番查閱資料,發現這個問題得去想別的辦法去做,具體的做法有三種,如下:
1.放棄Return HttpNotFound(),適用throw new HttpException(404, "page not found");
2.讓所有的Controller繼承自BaseController,然后BaseController重寫HttpNotFound方法,代碼如下:
protected override HttpNotFoundResult HttpNotFound(string statusDescription) { this.Response.StatusCode = 404; this.Response.TrySkipIisCustomErrors = true; Response.Clear(); Response.Redirect("~/FileNotFound.html"); Response.End(); return null; }
3.使用Fliter來處理異常,代碼如下;
public class CustomViewForHttpStatusResultFilter : IResultFilter, IExceptionFilter { string viewName; int statusCode; #region Ctor public CustomViewForHttpStatusResultFilter(HttpStatusCodeResult prototype, string viewName) : this(prototype.StatusCode, viewName) { } public CustomViewForHttpStatusResultFilter(int statusCode, string viewName) { this.viewName = viewName; this.statusCode = statusCode; } #endregion public void OnResultExecuted(ResultExecutedContext filterContext) { HttpStatusCodeResult httpStatusCodeResult = filterContext.Result as HttpStatusCodeResult; //比較重要的一句,當請求完成后,發現 if (httpStatusCodeResult != null && httpStatusCodeResult.StatusCode == statusCode) { ExecuteCustomViewResult(filterContext.Controller.ControllerContext); } } public void OnResultExecuting(ResultExecutingContext filterContext) { } public void OnException(ExceptionContext filterContext) { HttpException httpException = filterContext.Exception as HttpException; if (httpException != null && httpException.GetHttpCode() == statusCode) { ExecuteCustomViewResult(filterContext.Controller.ControllerContext); // This causes ELMAH not to log exceptions, so commented out //filterContext.ExceptionHandled = true; } } void ExecuteCustomViewResult(ControllerContext controllerContext) { ViewResult viewResult = new ViewResult(); viewResult.ViewName = viewName; viewResult.ViewData = controllerContext.Controller.ViewData; viewResult.TempData = controllerContext.Controller.TempData; viewResult.ExecuteResult(controllerContext); controllerContext.HttpContext.Response.TrySkipIisCustomErrors = true; } }