閱讀508 返回首頁    go 阿裏雲 go 技術社區[雲棲]


集成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,所以直接就會導向到出錯界麵,並顯示我們替換後的異常信息。

image


作者:蔣金楠
微信公眾賬號:大內老A
微博:www.weibo.com/artech
如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識別二維碼)關注個人公眾號(原來公眾帳號蔣金楠的自媒體將會停用)。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出原文連接,否則保留追究法律責任的權利。
原文鏈接

最後更新:2017-10-26 14:34:13

  上一篇:go  通過一個模擬程序讓你明白WCF大致的執行流程
  下一篇:go  為ASP.NET MVC創建一個基於Unity的ControllerFactory