異常篩選器用於實現IExceptionFilter接口,並在ASP.NET MVC管道執行期間引起了未處理的異常時執行。異常篩選器可用於執行諸如日誌記錄或顯示錯誤頁之類的任務。HandleErrorAttribute類是異常篩選器的一個示例。html
先來看看HandleErrorAttribute類的定義:git
#region 程序集 System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 // D:\Practice\MVC\自定義異常過濾器\MVCCuetomerExcepFilter\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll #endregion namespace System.Web.Mvc { // // 摘要: // 表示一個特性,該特性用於處理由操做方法引起的異常。 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class HandleErrorAttribute : FilterAttribute, IExceptionFilter { // // 摘要: // 初始化 System.Web.Mvc.HandleErrorAttribute 類的新實例。 public HandleErrorAttribute(); // // 摘要: // 獲取或設置異常的類型。 // // 返回結果: // 異常的類型。 public Type ExceptionType { get; set; } // // 摘要: // 獲取或設置用於顯示異常信息的母版視圖。 // // 返回結果: // 母版視圖。 public string Master { get; set; } // // 摘要: // 獲取此特性的惟一標識符。 // // 返回結果: // 此特性的惟一標識符。 public override object TypeId { get; } // // 摘要: // 獲取或設置用於顯示異常信息的頁視圖。 // // 返回結果: // 頁視圖。 public string View { get; set; } // // 摘要: // 在發生異常時調用。 // // 參數: // filterContext: // 操做篩選器上下文。 // // 異常: // T:System.ArgumentNullException: // filterContext 參數爲 null。 public virtual void OnException(ExceptionContext filterContext); } }
從代碼中能夠看出HandleErrorAttribute繼承了IExceptionFilter接口,而且有一個虛方法,若是要自定義異常過濾器,只須要繼承HandleErrorAttribute類並重寫HandleErrorAttribute類裏面的虛方法便可。github
新建一個ExceptionFilters類繼承自HandleErrorAttribute,並重寫OnException方法,代碼以下:ide
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MVCCuetomerExcepFilter.Extension { /// <summary> /// 異常過濾器 /// </summary> public class ExceptionFilters : HandleErrorAttribute { /// <summary> /// 在異常發生時調用 /// </summary> /// <param name="filterContext"></param> public override void OnException(ExceptionContext filterContext) { // 判斷是否已經處理過異常 if(!filterContext.ExceptionHandled) { // 獲取出現異常的controller和action名稱,用於記錄 string strControllerName = filterContext.RouteData.Values["controller"].ToString(); string strActionName = filterContext.RouteData.Values["action"].ToString(); // 定義一個HandleErrorInfo,用於Error視圖展現異常信息 HandleErrorInfo info = new HandleErrorInfo(filterContext.Exception, strControllerName, strActionName); ViewResult result = new ViewResult { ViewName = this.View, // 定義ViewData,泛型 ViewData = new ViewDataDictionary<HandleErrorInfo>(info) }; // 設置操做結果 filterContext.Result = result; // 設置已經處理過異常 filterContext.ExceptionHandled = true; } //base.OnException(filterContext); } } }
新建一個控制器,代碼以下:測試
using MVCCuetomerExcepFilter.Extension; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MVCCuetomerExcepFilter.Controllers { public class ExceptionController : Controller { // GET: Exception /// <summary> /// View表示發生異常時指定的視圖 /// 這裏表示發生異常時使用ExceptionDetails視圖 /// </summary> /// <returns></returns> [ExceptionFilters(View =("ExceptionDetails"))] public ActionResult Index() { // 測試拋出異常 throw new NullReferenceException("測試拋出的異常"); } } }
異常發生時使用ExceptionDetails視圖,因此在Shared文件夾裏面新建ExceptionDetails視圖,代碼以下:ui
<!--使用強類型視圖--> @model System.Web.Mvc.HandleErrorInfo @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>異常</title> </head> <body> <p> 拋錯控制器:<b>@Model.ControllerName</b> 拋錯方法:<b>@Model.ActionName</b> 拋錯類型:<b> @Model.Exception.GetType().Name </b> </p> <p> 異常信息:<b>@Model.Exception.Message</b> </p> <p> 堆棧信息: </p> <pre>@Model.Exception.StackTrace</pre> </body> </html>
運行程序,訪問Exception控制器的Index方法,效果以下:this
上面的案例演示了一個自定義異常類,很明顯比HandleError要靈活,在自定義異常類裏面能夠寫不少與業務相關的代碼。spa
GitHub代碼地址:git@github.com:JiangXiaoLiang1988/CustomerHandleErrorFilter.git日誌