<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ASP.NET MVC集成EntLib實現“自動化”異常處理[實例篇]

      個人覺得異常處理對于程序員來說是最為熟悉的同時也是最難掌握的。說它熟悉,因為僅僅就是try/catch/finally而已。說它難以掌握,則是因為很多開發人員卻說不清楚try/catch/finally應該置于何處?什么情況下需要對異常進行日志記錄?什么情況下需要對異常進行封裝?什么情況下需要對異常進行替換?對于捕獲的異常,在什么情況下需要將其再次拋出?什么情況下則不需要?

      合理的異常處理應該是場景驅動的,在不同的場景下,采用的異常處理策略往往是不同的。異常處理的策略應該是可配置的,因為應用程序出現怎樣的異常往往是不可預測的,現有異常策略的不足往往需要在真正出現某種異常的時候才會體現出來,所以我們需要一種動態可配置的異常處理策略維護方式。目前有一些開源的異常處理框架提供了這種可配置的、場景驅動的異常處理方式,EntLib的Exception Handling Application Block(以下簡稱EHAB)就是一個不錯的選擇。[源代碼從這里下載][本文已經同步到《How ASP.NET MVC Works?》中]

      目錄
      一、通過指定Handle-Error-Action響應請求
      二、通過Error View顯示錯誤消息
      三、自動創建JsonResult響應Ajax請求

      一、通過指定Handle-Error-Action響應請求

      在正式介紹如何通過擴展實現與EntLib以實現自動化異常處理之前,我們不妨先來體驗一下異常處理具有怎樣的“自動化”特性。以用戶登錄場景為例,我們在通過Visual Studio的ASP.NET MVC項目模板創建的Web應用中定義了如下一個簡單的數據類型LoginInfo封裝用戶登錄需要輸入的用戶名和密碼。

         1: public class LoginInfo
         2: {
         3:     [DisplayName("用戶名")]
         4:     [Required(ErrorMessage="請輸入{0}")]
         5:     public string UserName { get; set; }
         6:  
         7:     [DisplayName("密碼")]
         8:     [Required(ErrorMessage = "請輸入{0}")]
         9:     [DataType(DataType.Password)]
        10:     public string Password { get; set; }
        11: }

      然后我們定義了如下一個HomeController?;贖TTP-GET的Action方法Index將會呈現一個用戶登錄View,該View使用創建的LoginInfo對象作為其Model。真正的用戶驗證邏輯定義在另一個應用了HttpPostAttrubute特性的Index方法中:如果用戶名不為Foo,拋出InvalidUserNameException異常;如果密碼不是“password”,則拋出InvalidPasswordException異常。InvalidUserNameException和InvalidPasswordException是我們自定義的兩種異常類型。

         1: [ExceptionPolicy("defaultPolicy")]
         2: public class HomeController : ExtendedController
         3: {
         4:     public ActionResult Index()
         5:     {
         6:         return View(new LoginInfo());
         7:     }
         8:  
         9:     [HttpPost]
        10:     [HandleErrorAction("OnIndexError")]
        11:     public ActionResult Index(LoginInfo loginInfo)
        12:     {
        13:         if (string.Compare(loginInfo.UserName, "foo", true) != 0)
        14:         {
        15:             throw new InvalidUserNameException();
        16:         }
        17:  
        18:         if (loginInfo.Password != "password")
        19:         {
        20:             throw new InvalidPasswordException();
        21:         }
        22:         return View(loginInfo);
        23:     }
        24:  
        25:     [HttpPost]
        26:     public ActionResult OnIndexError(LoginInfo loginInfo)
        27:     {
        28:         return View(loginInfo);
        29:     }
        30: }

      上面定義的HomeController具有三點與自動化異常處理相關的地方:

      • HomeController繼承自自定義的基類ExtendedController,后者完成了對異常的自動化處理。
      • HomeController類型上應用了自定義的ExceptionPolicyAttribute特性用于指定默認采用的異常處理策略名稱(“defaultPolicy”)。
      • 基于HTTP-POST的Index方法上應用了HandleErrorActionAttribute特性用于指定一個Handle-Error-Action名稱,當異常在目標Action執行過程中拋出并通過EHAB處理后,指定的Action會被執行以實現對請求的響應。對于我們的例子來說,從Index方法拋出的異常被處理后會調用OnIndexError方法作為對當前請求的響應。

      下面是代表登錄頁面的View的定義,這是一個Model類型為LoginInfo的強類型View。在該View中,作為Model的LoginInfo對象以編輯默認呈現在一個表單中,表單中提供了一個“登錄”提交表單。除此之外,View中還具有個ValidationSummary。

         1: @model LoginInfo
         2: <html>
         3:     <head>
         4:         <title>用戶登錄</title>
         5:         <style type="text/css">
         6:             .validation-summary-errors{color:Red}
         7:         </style>
         8:     </head>
         9:     <body>
        10:         @using (Html.BeginForm())
        11:         { 
        12:             @Html.ValidationSummary(true)
        13:             @Html.EditorForModel()
        14:             <input type="submit" value="登錄" />
        15:         }
        16:     </body>
        17: </html>

      通過HomeController的定義我們知道兩種不同類型的異常(InvalidUserNameException和InvalidPasswordException)分別在輸入無效用戶名和密碼是被拋出來,而我們需要處理的就是這兩種類型的異常。正對它們的異常處理策略定義在如下的配置中,策略名稱就是通過應用在HomeController上的ExceptionPolicyAttribute特性指定的“defaultPolicy”。

         1: <configuration>
         2:   <configSections>
         3:       <section name="exceptionHandling" 
         4:          type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" />
         5:    </configSections>
         6:   <exceptionHandling>
         7:     <exceptionPolicies>
         8:       <add name="defaultPolicy">
         9:         <exceptionTypes>
        10:           <add type="MvcApp.InvalidUserNameException, MvcApp" postHandlingAction="ThrowNewException" name="InvalidUserNameException">
        11:             <exceptionHandlers>
        12:               <add name ="ErrorMessageHandler" type="MvcApp.ErrorMessageHandler, MvcApp" errorMessage="用戶名不存在"/>
        13:             </exceptionHandlers>
        14:           </add>
        15:  
        16:           <add type="MvcApp.InvalidPasswordException, MvcApp" postHandlingAction="ThrowNewException" name="InvalidPasswordException">
        17:             <exceptionHandlers>
        18:               <add name ="ErrorMessageHandler" type="MvcApp.ErrorMessageHandler, MvcApp" errorMessage="密碼與用戶名不匹配"/>
        19:             </exceptionHandlers>
        20:           </add>
        21:         </exceptionTypes>
        22:       </add>
        23:     </exceptionPolicies>
        24:   </exceptionHandling>
        25:   ...
        26: </configuration>

      通過上面的這樣異常策略配置可以看到:我們使用一個自定義的名為ErrorMessageHandler的ExceptionHandler來處理拋出來的InvalidUserNameException和InvalidPasswordException異常,而ErrorMessageHandler僅僅是指定一個友好的錯誤消息,該消息一般會呈現給最終的用戶。運行該程序后一個用于登錄頁面會呈現出來,當我們輸入錯誤的用戶名和密碼的時候,相應的錯誤消息(在配置中通過ErrorMessageHandler設置的錯誤消息)會以如圖7-16所示的效果顯示出來,其實整個View是通過執行Action方法OnIndexError返回的ViewResult呈現出來的。

      image

      二、通過Error View顯示錯誤消息

      除了通過執行對應的Handle-Error-Action來呈現異常處理后的最終結果之外,還支持錯誤頁面的錯誤呈現方法。簡單起見,我們只是用名稱為Error的View來作為最終的錯誤頁面。為了演示基于錯誤頁面的呈現方式,我們按照如下的方式重新定義了\Views\Shared\目錄下的Error.cshtml。

         1: @model ExtendedHandleErrorInfo
         2: @{
         3:     Layout = null;
         4: }
         5: <!DOCTYPE html>
         6: <html>
         7: <head>
         8:     <meta name="viewport" content="width=device-width" />
         9:     <title>Error</title>
        10:     <style type="text/css">
        11:         h3 {color:Red;}
        12:     </style>
        13: </head>
        14: <body>
        15:     <h3>
        16:         @Html.DisplayFor(m=>m.ErrorMessage)
        17:     </h3>
        18:     <ul>
        19:         <li>Controller: @Html.DisplayFor(m => m.ControllerName)</li>
        20:         <li>Action: @Html.DisplayFor(m => m.ActionName)</li>
        21:         <li>Exception: 
        22:             <ul>
        23:                 <li>Message: @Html.DisplayFor(m => m.Exception.Message)</li>
        24:                 <li>Type: @Model.Exception.GetType().FullName</li>
        25:                 <li>StackTrace: @Html.DisplayFor(m => m.Exception.StackTrace)</li>
        26:             </ul>
        27:         </li>
        28:     </ul>
        29: </body>
        30: </html>

      上面這個View的Model類型是具有如下定義的ExtendedHandleErrorInfo。它繼承自HandleErrorInfo,只額外定義了一個表示錯誤消息的ErrorMessage屬性。在上面的這個View中,我們將錯誤消息、異常類型和StackTrace和當前Controller/Action的名稱呈現出來。

         1: public class ExtendedHandleErrorInfo : HandleErrorInfo
         2: {
         3:     public string ErrorMessage { get; private set; }
         4:     public ExtendedHandleErrorInfo(Exception exception, string controllerName, string actionName, string errorMessage)
         5:         : base(exception, controllerName, actionName)
         6:     {
         7:         this.ErrorMessage = errorMessage;
         8:     }
         9: }

      當利用EntLib的EHAB對從Index方法中拋出的異常進行處理后采用錯誤View的方式來響應請求,我們需要按照如下的方式將應用在該方法上的HandleErrorActionAttribute特性注釋掉。

         1: [ExceptionPolicy("defaultPolicy")]
         2: public class HomeController : ExtendedController
         3: {    
         4:     //其他成員
         5:     [HttpPost]
         6:     //[HandleErrorAction("OnIndexError")]
         7:     public ActionResult Index(LoginInfo loginInfo)
         8:     {
         9:         //省略實現
        10:     }
        11: }

      再次運行該程序并分別輸入錯誤的用戶名和密碼后,默認的錯誤View(Error.cshtml)將會以如下圖所示地效果把處理后的異常結果呈現出來。

      image

      三、自動創建JsonResult響應Ajax請求

      用于實施認證的Action方法Index可以通過普通的HTTP-POST的形式來調用,同樣也可以通過Ajax請求的方式來調用。對于Ajax請求來說,我們最終會將通過EntLib處理后的異常封裝成如下一個類型為ExceptionDetail的對象。如下面的代碼片斷所示,ExceptionDetail具有與Exception對應的屬性設置。最終根據拋出異常對象創建的ExceptionDetail對象會被用于創建一個JsonResult對象對當前Ajax請求予以響應。

         1: public class ExceptionDetail
         2: {
         3:     public ExceptionDetail(Exception exception,string errorMessage=null)
         4:     {
         5:         this.HelpLink = exception.HelpLink;
         6:         this.Message = string.IsNullOrEmpty(errorMessage) ? exception.Message : errorMessage;
         7:         this.StackTrace = exception.StackTrace;
         8:         this.Type = exception.GetType().ToString();
         9:         if (exception.InnerException != null)
        10:         {
        11:             this.InnerException = new ExceptionDetail(exception.InnerException);
        12:         }
        13:     }
        14:  
        15:     public string HelpLink { get; set; }
        16:     public ExceptionDetail InnerException { get; set; }
        17:     public string Message { get; set; }
        18:     public string StackTrace { get; set; }
        19:     public string Type { get; set; }
        20: }

      當客戶端接收到回復的Json對象后,可以通過檢測其是否具有一個ExceptionType屬性(對于一個ExceptionDetail對象來說,該屬性不可能為Null)來判斷是否發生異常。作為演示我們對Action方法Index對應的View進行了如下的改動。

         1: @model LoginInfo
         2: <html>
         3:     <head>
         4:         <title>用戶登錄</title>
         5:         <script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.6.2.js")"></script>
         1:  
         2:         <script type="text/javascript" src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")">
         1: </script>
         2:         <script type="text/javascript">
         3:             function login(data) {
         4:                 if (data.ExceptionType) {
         5:                     alert(data.Message);
         6:                 }
         7:                 else {
         8:                     alert("認證成功");
         9:                 }
        10:             }
        11:         
      </script>
         6:     </head>
         7:     <body>
         8:         @{
         9:             AjaxOptions options = new  AjaxOptions{OnSuccess = "login"};
        10:          }
        11:         @using (Ajax.BeginForm(options))
        12:         { 
        13:             @Html.EditorForModel()
        14:             <input type="submit" value="登錄" />
        15:         }
        16:     </body>
        17: </html>

      如上面的代碼片斷所示,我們通過調用AjaxHelper的BuginForm生成了一個以Ajax形式提交的表單。表單成功提交(服務端因對拋出的異常進行處理而返回一個封裝異常的Json對象,對于提交表單的Ajax請求來說依然屬于成功提交)后會調用我們定義的回調函數login。在該JavaScript函數中,我們通過得到的對象是否具有一個ExceptionType屬性來判斷服務端是否拋出異常。如果拋出異常,在通過調用alert方法將錯誤消息顯示出來,否則顯示“認證成功”。我們再次運行我們的程序并分別輸入不合法的用戶名和密碼,相應的錯誤消息會以對話框的形式顯示出來,具體的顯示效果如下圖所示。

      image

      ASP.NET MVC集成EntLib實現“自動化”異常處理[實例篇]
      ASP.NET MVC集成EntLib實現“自動化”異常處理[實現篇]

      posted @ 2012-08-07 07:59  Artech  閱讀(5152)  評論(15)    收藏  舉報
      主站蜘蛛池模板: 国产初高中生视频在线观看| 亚洲av一本二本三本| 国产免费又黄又爽又色毛| 中文字幕av日韩有码| 97人妻人人揉人人躁人人 | 亚洲国产一成人久久精品| 免费无码又爽又刺激高潮的app| 苍井空一区二区波多野结衣av| 亚洲狠狠狠一区二区三区| 成年人尤物视频在线观看| 久久婷婷国产精品香蕉| 又爽又黄又无遮挡的激情视频| 人妻系列无码专区无码中出| 熟女系列丰满熟妇AV| 久久久久国产精品人妻 | 久久天天躁狠狠躁夜夜躁| 少妇和邻居做不戴套视频| 嘉黎县| 国产成人精品区一区二区| 综合色一色综合久久网| 亚洲国产欧美在线人成| 国产美女久久久亚洲综合| 久久国产自偷自免费一区| 蜜芽亚洲AV无码精品国产午夜| 最新国产AV最新国产在钱| 亚洲精品一区国产欧美| 亚洲男人第一无码av网站| 国产婷婷综合在线视频| 亚洲精品人妻中文字幕| 丁香五月婷激情综合第九色| 亚洲国产精品无码久久久| 欧美大肥婆大肥bbbbb| 日日躁夜夜躁狠狠躁超碰97| 国产无套粉嫩白浆在线| 国产亚洲精品久久久久婷婷图片| 蜜桃视频一区二区三区四| 91人妻熟妇在线视频| 国产成人av一区二区三区不卡| 亚洲一区二区三区十八禁| 一级国产在线观看高清| 又爽又黄又无遮挡的激情视频|