集成EntLib實現ASP.NET MVC的異常處理
本篇通過自定義ASP.NET MVC的異常篩選器實現了與EntLib的EHAB(Exception Handling Application Block)的集成,使我們可以通過配置的方式來定義異常處理策略,並最終通過錯誤頁麵顯示被處理過的異常信息。[源代碼從這裏下載]
我們知道ASP.NET MVC具有一個類型為HandleErrorAttribute的異常篩選器可以起到錯誤頁麵的導向作用。在這裏我直接讓我們自定義的異常篩選器繼承它,為此我們定義了如下一個名稱為ExtendedHandleErrorAttribute的類型。我們通過指定異常處理策略的配置名稱來創建ExtendedHandleErrorAttribute,而屬性ExceptionPolicy則表示具體的異常處理策略。在重寫的OnException方法中,我們在try/catch中調用了ExceptionPolicyImpl的HandleException方法,而傳入該方法的對象為需要處理的異常。捕獲的異常可能是原來的異常,也可能是處理後的異常,這依賴於postHandlingAction的設置。
1: public class ExceptionHandlingAttribute: HandleErrorAttribute
2: {
3: public ExceptionPolicyImpl ExceptionPolicy { get; private set; }
4:
5: public ExceptionHandlingAttribute(string exceptionPolicyName)
6: {
7: this.ExceptionPolicy = EnterpriseLibraryContainer.Current.GetInstance<ExceptionPolicyImpl>(exceptionPolicyName);
8: }
9:
10: public override void OnException(ExceptionContext filterContext)
11: {
12: try
13: {
14: this.ExceptionPolicy.HandleException(filterContext.Exception);
15: }
16: catch (Exception ex)
17: {
18: filterContext.Exception = ex;
19: base.OnException(filterContext);
20: }
21: }
22: }
接下來我們來定義顯示錯誤信息的View。我們在Views\Shared目錄下創建一個Model類型為HandleErrorInfo的Error.cshtml文件,下麵是整個文件的內容。從中可以看出,我們顯示了異常的消息、類型和堆棧追蹤信息。
1: @model System.Web.Mvc.HandleErrorInfo
2: @{
3: ViewBag.Title = "Error";
4: }
5: <h2>@this.Model.Exception.Message</h2>
6: <p><b>Exception Type: </b>@this.Model.Exception.GetType()</p>
7: <p><b>StackTrace: </b>@this.Model.Exception.StackTrace</p>
然後我們如下一個名稱為HomeController的控製器,在Action方法Index中,我們執行一個被除數為零的整形除法運算讓它拋出DivideByZeroException異常。而我們自定義的異常篩選器直接應用在了HomeController類型上,指定異常處理策略名稱為UI Policy,View屬性被設置為上麵創建的用於顯示錯誤信息的View名稱。
1: [ExtendedHandleError("UI Policy", View = "Error")]
2: public class HomeController : Controller
3: {
4: public ActionResult Index()
5: {
6: int x = 1;
7: int y = 0;
8: int result = x / y;
9: return View();
10: }
11: }
最後來看定義的Web.config中的異常處理策略,針對拋出的DivideByZeroException異常,我們將其替換成了CalculationErrorException異常,並指定了被替換後的異常消息為”Calculation Error…”。至於PostHandlingAction屬性,則被設置為ThrowNewException,意味著被處理後的異常會被拋出來。對了我們的例子來說,也就是說被替換後的CalculationErrorException會被拋出。
1: <configuration>
2: <configSections>
3: <section name="exceptionHandling"
4: type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"/>
5: </configSections>
6: ...
7: <exceptionHandling>
8: <exceptionPolicies>
9: <add name="UI Policy">
10: <exceptionTypes>
11: <add name="InvalidOperationException"
12: type="System.DivideByZeroException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
13: postHandlingAction="ThrowNewException" >
14: <exceptionHandlers>
15: <add name="ReplaceHandler"
16: type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler,Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=5.0.414.0, Culture=neutral, PublicKeyToken=a20767533a162583"
17: replaceExceptionType="Artech.Web.Mvc.Extensions.CalculationException, EhabIntegration"
18: exceptionMessage="Calculation Error..."/>
19: </exceptionHandlers>
20: </add>
21: </exceptionTypes>
22: </add>
23: </exceptionPolicies>
24: </exceptionHandling>
25: </configuration>
我們現在來運行我們的程序,由於HomeController和Index為默認的控製器和Action,所以直接就會導向到出錯界麵,並顯示我們替換後的異常信息。
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
最後更新:2017-10-26 14:34:13