http://2sharings.com/2015/asp-net-mvc-5-custom-404-500-error-hanlde
https://blog.csdn.net/yhyhyhy/article/details/51003683
?
?
ASP.NET MVC 5的開發中,服務器的各種錯誤[如:401(登錄授權驗證),403(禁止訪問),404(訪問頁面不存在),500(服務器內部錯誤)等]處理是必需考慮并解決的一個問題,如果不處理這些錯誤或者使用默認的錯誤頁面,那么用于用戶體驗來說就不是很友好了。嚴重的甚至可以暴露程序以及服務器的各種信息,給黑客以可乘之機。 網上關于ASP.NET MVC 5的服務器錯誤處理攔截問題沒有太全的總結和整理。今天用一個簡單實例來總結整理一下這方面的處理技巧。 首先是404頁面的處理,本示例利用Global.asax文件的Application_Error()方法來攔截,使用Server.GetLastError()方法獲取到服務器的最后一次錯誤作為HttpException,再根據httpException的GetHttpCode()方法獲取到的http狀態碼來處理404的頁面不存在的問題,Global.asax代碼如下:
protected void Application_Error(object sender, EventArgs e){Exception exception = Server.GetLastError();HttpException httpException = exception as HttpException; RouteData routeData = new RouteData(); routeData.Values.Add("controller", "Error"); switch (httpException.GetHttpCode()) { case 404: routeData.Values.Add("action", "HttpError404"); break; } Response.Clear(); Server.ClearError(); Response.TrySkipIisCustomErrors = true; IController errorController = new ErrorController(); errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); //Response.RedirectToRoute(new { controller = "Error", action = "HttpError404" }); }
以上的404錯誤處理是直接將事先制作好的HttpError404.cshtml視圖信息顯示在請求的頁面,如: 其次是401(未授權)頁面的攔截處理,本示例是創建了一個名為AuthorizeCheckAttribute屬性類,此類繼承至AuthorizeAttribute類,在AuthorizeCheckAttribute類中,重寫了HandleUnauthorizedRequest方法,我們中此方法中來處理所有需要授權但未授權訪問的請求,然后再在需要授權訪問的控制器或者Action上使用AuthorizeCheck屬性,AuthorizeCheckAttribute屬性類的代碼如下:
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { base.HandleUnauthorizedRequest(filterContext); if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { try { filterContext.Controller.TempData.Add("Alert", new Alert { Type = AlertType.Error, Message = "請登錄后訪問" }); } catch { } filterContext.Result = new ViewResult { TempData = filterContext.Controller.TempData, ViewName = "~/Views/Error/HttpError401.cshtml" }; //new RedirectResult("~/error/httperror401"); } }
需要授權訪問的Action如下:
[AuthorizeCheck]public ActionResult UnAuthorize(){return View(); }
這樣,如果在未登錄授權的情況下訪問UnAuthorize這個Action,那么就會被攔截到。我們可以在攔截器里任意處理錯誤信息了,比如把錯誤記錄到日志等。 最后,我們來處理的服務器的500內部錯誤。首先創建一個名為CustomHandleErrorAttribute的自定義錯誤處理屬性類,此類繼承至HandleErrorAttribute類,在CustomHandleErrorAttribute類中重寫OnException方法,代碼如下:
public override void OnException(ExceptionContext filterContext){base.OnException(filterContext);Exception exception = filterContext.Exception;try { //TODO:寫錯誤日志 filterContext.Controller.TempData.Add("Alert", new Alert { Type = AlertType.Error, Message = exception.ToString() }); } catch { } filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; //filterContext.Result = new RedirectResult("~/error/httperror500"); filterContext.Result = new ViewResult { TempData=filterContext.Controller.TempData, ViewName = "~/Views/Error/HttpError500.cshtml" }; //var Result = this.View("Error", new HandleErrorInfo(exception, //filterContext.RouteData.Values["controller"].ToString(), //filterContext.RouteData.Values["action"].ToString())); //filterContext.Result = Result; }
以上代碼中,我們使用了filterContext.Result屬性來設置攔截到內部錯誤后的返回視圖名字和返回的信息。當然,在OnException這個重寫方法中,我們還可以處理日志等操作,根據自已需要來實現就行。寫好這個類后,我們再修改FilterConfig類的RegisterGlobalFilters的方法,如下:
public class FilterConfig{public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new CustomHandleErrorAttribute()); } }
當然,我們事先已經在Global.asax文件中注冊了全局攔截配置了,Application_Start代碼如下:
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
好了,以上就是關于ASP.NET MVC 5中處理各種服務器錯誤的自定義頁面的操作,希望對你有所幫助。 如果你有更好的實現方法,也歡迎留言交流。 最后,我把本實例的代碼提供如下,點擊這里下載。