一、概述
MVC4框架自帶了定義錯誤頁,該頁面位於Shared/Error,該頁面能夠顯示系統未能捕獲的異常,如何才能使用該頁面;
二、使用步驟:
1、配置WebConfig文件,在System.Web節點下加上
<customErrors mode="On" defaultRedirect="~/Shared/Error" />
翻閱一些大神寫的博客,在他們的博客中指出defaultRedirect是指向錯誤頁面的URL,可是經過本人測試的時候,發現在MVC4中這種說法並不准,在MVC中,有一套默認的機制(這部分代碼被微軟封裝,無法閱讀),該機制能夠把錯誤信息通過HandleError屬性指向Shared/Error頁面,也就是說配置System.Web節點,可以省略defaultRedirect
customErrors mode="On"/>
2、Global文件,添加HandleEffor屬性
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute(),1); }
在Global定義之后,也就是全局定義,其他Action和Control都不需要定義,默認使用HandleError控制屬性;
這樣就可以使用MVC4中系統默認的Error頁面;
三、自定義錯誤頁面
有些時候,我們想使用自定義的錯誤頁面,該怎么處理那,翻頁其他大牛寫的博客,看到有這種方式,自定義屬性Class繼承FileterAttribute,重寫OnException方法,代碼如下
public class BaseHandleErrorAttribute : FilterAttribute, IExceptionFilter { public void OnException(ExceptionContext filterContext) { if (filterContext.ExceptionHandled == true) { HttpException httpExce = filterContext.Exception as HttpException; if (httpExce != null && httpExce.GetHttpCode() != 500)//為什么要特別強調500 因為MVC處理HttpException的時候,如果為500 則會自動將其ExceptionHandled設置為true,那么我們就無法捕獲異常 { return; } } Exception exception = filterContext.Exception; if (exception != null) { HttpException httpException = exception as HttpException; if (httpException != null) { //網絡錯誤 filterContext.Controller.ViewBag.UrlRefer = filterContext.HttpContext.Request.UrlReferrer; int DataEroorCode = httpException.GetHttpCode(); if (DataEroorCode == 404) { filterContext.HttpContext.Response.Redirect("~/SysError/404"); } else if (DataEroorCode == 500) { filterContext.HttpContext.Response.Redirect("~/SysError/500"); } else filterContext.HttpContext.Response.Redirect("~/SysError/" + DataEroorCode); //寫入日志 記錄 filterContext.ExceptionHandled = true;//設置異常已經處理 } else { //編程或者系統錯誤,不處理,留給HandError處理 } } } }
將該屬性注冊到全局Global中,定義鋪貨異常等級
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new BaseHandleErrorAttribute(),0); filters.Add(new HandleErrorAttribute(),1); }
當然我們也可以不使用MVC框架自帶的Error頁面,定義一個Error404,如何使用這個頁面那 ,起始也挺簡單的,代碼如下
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new BaseHandleErrorAttribute(),0); filters.Add(new HandleErrorAttribute(View="Error404"),1); }
四、遇到問題總結
1、遇到重定向,URL指向aspxerrorpath,如:
http://local:8090/error/error.htm?aspxerrorpath=/cmt/p/3789549.html
出現這個問題的主要原因:
1>、Global沒有添加
filters.Add(new HandleErrorAttribute(View="Error404"))
2>、Shared目錄沒有Error頁面;
3>、如果存在Error頁面,但是頁面是用了布局Layout,組成的Error頁面存在錯誤,比如ModeView數據不對等,需要詳查;
2、自定義Error的其他方式
翻頁其他大牛寫的文章時候,返現也可以使用Gloal中的Application_Error事件方法處理,比如博主@dudu寫的異常處理方式;
代碼粘貼如下:
protected void Application_Error(Object sender, EventArgs e) { var lastError = Server.GetLastError(); if (lastError != null) { var httpError = lastError as HttpException; if (httpError != null) { //ASP.NET的400與404錯誤不記錄日志,並都以自定義404頁面響應 var httpCode = httpError.GetHttpCode(); if (httpCode == 400 || httpCode == 404) { Response.StatusCode = 404;//在IIS中配置自定義404頁面 Server.ClearError(); return; } Logger.Default.Error("Application_Error_" + httpCode, httpError); } //對於路徑錯誤不記錄日志,並都以自定義404頁面響應 if (lastError.TargetSite.ReflectedType == typeof(System.IO.Path)) { Response.StatusCode = 404; Server.ClearError(); return; } Logger.Default.Error("Application_Error", lastError); Response.StatusCode = 500; Server.ClearError(); } }
實現樣式多樣,只要實現功能就是最好;