您好,登錄后才能下訂單哦!
小編給大家分享一下ASP.NET MVC中異常處理和自定義錯誤頁的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!
一、應用場景
對于B/S應用程序,在部署到正式環境運行的過程中,很有可能出現一些在前期測試過程中沒有發現的一些異常或者錯誤,或者說只有在特定條件滿足時才會發生的一些異常,對于使用ASP.NET MVC開發的應用程序站點,在部署到IIS上后,如果開發人員未對程序進行錯誤處理,那么一旦程序出現未處理的錯誤或異常,用戶將看到一個讓人感到及其困惑的錯誤堆棧跟蹤頁面,使得站點的用戶體驗下降,從程序的角度上來說,不做自定義錯誤處理也不利于程序出問題時的根源查找,因為很多時候有些錯誤只在特定條件下滿足時才重現,一旦錯過,可能就需要花大量時間去測試來重現問題,如果此時開發人員有對程序中的運行時異常進行日志記錄,那么或許將提供一些有價值的錯誤根源信息,下面我將向下大家講解如何實現自定義異常處理并跳轉到友好的錯誤提示頁面。
二、異常處理&自定義錯誤頁
1、通過異常過濾器 實現異常處理和自定義錯誤頁
asp.net mvc 提供了 異常過濾器 的方式來實現當執行controller中某個action方法時拋出了未處理的異常時的捕捉,mvc中的異常過濾器是以特性(Attribute)的形式存在的,定義一個自定義異常過濾器只需要兩個步驟:
1、定義一個類,繼承FilterAttribute類,并實現IExceptionFilter接口 2、應用自定義異常過濾器至指定的 action方法 或 controller類 或 全局應用。
異常過濾器代碼
using log4net; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Blog20180413.Filters { public class CustomExceptionFilterAttribute : FilterAttribute, IExceptionFilter { //log4net組件,用于日志記錄。 static readonly ILog log = LogManager.GetLogger(typeof(CustomExceptionFilterAttribute)); public void OnException(ExceptionContext filterContext) { //對捕獲到的異常信息進行日志記錄,方便開發人員排查問題。 log.Error("應用程序異常", filterContext.Exception); //跳轉到自定義的錯誤頁,增強用戶體驗。 ActionResult result = new ViewResult() { ViewName = "CustomErrorPage" }; filterContext.Result = result; //異常處理結束后,一定要將ExceptionHandled設置為true,否則仍然會繼續拋出錯誤。 filterContext.ExceptionHandled = true; } } }
使用異常過濾器
using Blog20180413.Filters; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace Blog20180413.Controllers { public class TestExceptionHandleController : Controller { [CustomExceptionFilter] public ActionResult Index() { string str = string.Empty; //將拋出轉換異常 int result = int.Parse(str); return View(); } } }
注意:
第二個步驟中提到,可以將自定義異常過濾器 只應用到 action或者controller,如果只想將指定的異常過濾器以特性的形式應用到指定的一個或者多個controller或者action,而不想應用到所有的controller或者action,那么必須將該異常過濾器繼承FilterAttribute類,這是因為mvc框架是通過FilterAttributeFilterProvider.GetFilters來獲取標記在指定controller或者action上的異常過濾器特性的,而GetFilters內部邏輯要求必須繼承自FilterAttribute類。
如果需要將自定義的異常過濾器應用到所有的controller的action上,那么需要將該自定義異常過濾器注冊到全局,代碼如下:
using Blog20180413.Filters; using System.Web; using System.Web.Mvc; namespace Blog20180413 { public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new CustomExceptionFilterAttribute()); } } }
2、通過在Global.asax 中定義Application_Error方法 實現異常處理和自定義錯誤頁
上面提到的 自定義異常過濾器只能捕獲在執行action方法過程中拋出的異常(即使注冊為全局過濾器也只能捕獲action方法執行過程中拋出的異常),如果需要捕獲更高級別的異常,也就是在請求執行過程中出現的任何異常(如在控制器的構造函數中拋出異常),那么可以使用該種方式,代碼如下:
using log4net; using log4net.Config; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace Blog20180413 { public class MvcApplication : System.Web.HttpApplication { static readonly ILog log = LogManager.GetLogger(typeof(MvcApplication)); protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); XmlConfigurator.ConfigureAndWatch(new FileInfo(Server.MapPath("~/web.config"))); } protected void Application_Error(object sender, EventArgs e) { Exception exception = Server.GetLastError(); //Server.ClearError(); //這里記錄錯誤日志信息 log.Error("MvcApplication 捕獲異常", exception); //跳轉到指定的自定義錯誤頁 Response.Redirect("/CustomErrorHandle/CustomErrorPage"); } } }
3、通過配置system.web->customErrors節點 實現自定義錯誤頁
當你的站點發生異常時,如果你只是想簡單的跳轉到一個自定義錯誤頁面,而不是對異常進一步處理時,那么你可以簡單的作如下配置操作即可:
需要在web.config中做如下配置:
<system.web> <customErrors mode="On" defaultRedirect="CustomErrorPage"> </customErrors> </system.web>
注意:這里的CustomErrorPage是一個視圖文件,放在Shared共享目錄下。
如果你注冊了HandleErrorAttribute異常過濾器到全局,那么在你的錯誤頁中將能獲取到和異常相關的一些信息。但此時配置到defaultRedirect的值的必須是Error
也就是自定義錯誤視圖頁面的名稱必須為Error.cshtml,并且放在Shared目錄,當然,你也可以通過在創建HandleErrorAttribute全局過濾器的過程中,設置器View屬性,這樣你就可以不用講錯誤視圖的名稱設置為Error了.如下:
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { HandleErrorAttribute errorAttribute = new HandleErrorAttribute(); errorAttribute.View = "CustomErrorPage"; filters.Add(errorAttribute); }
注冊HandleErrorAttribute(使用默認的錯誤視圖頁面文件名)
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); } }
定義Error.cshtml視圖頁
@{ Layout = null; } @model HandleErrorInfo <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Error</title> </head> <body> <div> @*通過HandleErrorAttribute異常過濾器捕獲到的異常信息存儲在Model屬性中*@ @Model.Exception.Message </div> </body> </html>
之所以通過注冊HandleErrorAttribute過濾器捕獲的異常在錯誤頁中能獲取異常信息可以看HandleErrorAttribute類的內部實現,發現加載錯誤視圖頁面的過程中,傳遞了一個HandleErrorInfo對象過去。
public virtual void OnException(ExceptionContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } if (!filterContext.IsChildAction && (!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled)) { Exception innerException = filterContext.Exception; if ((new HttpException(null, innerException).GetHttpCode() == 500) && this.ExceptionType.IsInstanceOfType(innerException)) { string controllerName = (string) filterContext.RouteData.Values["controller"]; string actionName = (string) filterContext.RouteData.Values["action"]; HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName); ViewResult result = new ViewResult { ViewName = this.View, MasterName = this.Master, ViewData = new ViewDataDictionary<HandleErrorInfo>(model), TempData = filterContext.Controller.TempData }; filterContext.Result = result; filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.Clear(); filterContext.HttpContext.Response.StatusCode = 500; filterContext.HttpContext.Response.TrySkipIisCustomErrors = true; } } }
public string View { get { if (string.IsNullOrEmpty(this._view)) { return "Error"; } return this._view; } set => (this._view = value); }
看完了這篇文章,相信你對“ASP.NET MVC中異常處理和自定義錯誤頁的示例分析”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。