欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

ASP.NETMVC對異常進行處理的-創(chuàng)新互聯(lián)

小編給大家分享一下ASP.NET MVC對異常進行處理的,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

九臺ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為成都創(chuàng)新互聯(lián)的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!

ASP.NET MVC是一個極具可擴展開發(fā)框架,在這篇文章中我將通過它的擴展實現(xiàn)與EntLib的集成,并提供一個完整的解決異常處理解決方案。

EntLib的異常處理應(yīng)用塊(Exception Handling Application Block)是一個不錯的異常處理框架,它使我們可以采用配置的方式來定義異常處理策略。而ASP.NET MVC是一個極具可擴展開發(fā)框架,在這篇文章中我將通過它的擴展實現(xiàn)與EntLib的集成,并提供一個完整的解決異常處理解決方案。

一、基本異常處理策略

我們首先來討論我們的解決方案具體采用的異常處理策略:

對于執(zhí)行Controller的某個Action方法拋出的異常,我們會按照指定配置策略進行處理。我們可以采取日志記錄、異常替換和封裝這些常用的異常處理方式;

對于處理后的異常,如果異常處理策略規(guī)定需要將其拋出,則會自動重定向到與異常類型匹配的出錯頁面。我們會維護一個異常類型和Error View的匹配關(guān)系;

對于處理后的異常,如果異常處理策略規(guī)定不需要將其拋出,則會執(zhí)行與當前Action操作相匹配的錯誤處理Action進行處理。異常處理Action方法默認采用“On{Action}Error”這樣的命名規(guī)則,而當前上下文會與異常處理操作方法的參數(shù)進行綁定。除次之外,我們會設(shè)置當前ModelState的錯誤信息;

如果用戶不曾定義相應(yīng)的異常處理Action,依然采用“錯誤頁面重定向”方式進行異常處理。

二、通過自定義Action處理異常

為了讓讀者對上面介紹的異常處理頁面有一個深刻的理解,我們來進行一個實例演示。該實例用于模擬用戶登錄,我們定義了如下一個只包含用戶名和密碼兩個屬性的Model:LoginInfoModel。

  namespace Artech.Mvc.ExceptionHandling.Models
   {
     public class LoginInfo
     {
       [Display(Name ="User Name")]
       [Required(ErrorMessage = "User Name is manadatory!")]
       public string UserName { get; set; }
   
       [Display(Name = "Password")]
      [DataType(DataType.Password)]
      [Required(ErrorMessage = "Password is manadatory!")]
      public string Password { get; set; }
    }
  }

我們定義了如下一個AccountController,它是我們自定義的BaseController的子類。AccountController在構(gòu)造的時候調(diào)用基類構(gòu)造函數(shù)指定的參數(shù)代表異常處理策略的配置名稱。SignIn方法代表用于進行“登錄”的操作,而OnSignInError就表示該操作對應(yīng)的異常處理操作。如果在SignIn操作中拋出的異常經(jīng)過處理后無需再拋出,則會通過調(diào)用OnSignInError,而此時ModelState已經(jīng)被設(shè)置了相應(yīng)的錯誤消息。

  public class AccountController BaseController
   {
     public AccountController()
       base("myPolicy")
     { }
   
     public ActionResult SignIn()
     {
       return View(new LoginInfo());
    }
    [HttpPost]
    public ActionResult SignIn(LoginInfo loginInfo)
    {
      if (!ModelState.IsValid)
      {
        return this.View(new LoginInfo { UserName = loginInfo.UserName });
      }
   
      if (loginInfo.UserName != "Foo")
      {
        throw new InvalidUserNameException();
      }
   
      if (loginInfo.Password != "password")
      {
        throw new UserNamePasswordNotMatchException();
      }
   
      ViewBag.Message = "Authentication Succeeds!";
      return this.View(new LoginInfo { UserName = loginInfo.UserName });
    }
   
    public ActionResult OnSignInError(string userName)
    {
      return this.View(new LoginInfo { UserName = userName });
    }
  }

具體定義在SignIn操作方法中的認證邏輯是這樣的:如果用戶名不是“Foo”則拋出InvalidUserNameException異常;如果密碼不是“password”則拋出UserNamePasswordNotMatchException異常。下面是SignIn操作對應(yīng)的View的定義:

  @model Artech.Mvc.ExceptionHandling.Models.LoginInfo
   @{
     ViewBag.Title = "SignIn";
   }
   @Html.ValidationSummary()
   @if (ViewBag.Messages != null)
   { 
     @ViewBag.Messages
   }
  @using (Html.BeginForm())
  { 
    @Html.EditorForModel()
    <input type="submit" value="SignIn" />
  }

在AccountController初始化時指定的異常處理策略“myPolicy”定義在如下的配置中。我們專門針對SignIn操作方法拋出的InvalidUserNameException和UserNamePasswordNotMatchException進行了處理,而ErrorMessageSettingHandler是我們自定義的異常處理器,它僅僅用于設(shè)置錯誤消息。如下面的代碼片斷所示,如果上述的這兩種類型的異常被拋出,最終的錯誤消息會被指定為“User name does not exist!”和“User name does not match password!”。

  <exceptionHandling>
    <exceptionPolicies>
     <add name="myPolicy">
      <exceptionTypes>
       <add name="InvalidUserNameException" 
          type="Artech.Mvc.ExceptionHandling.Models.InvalidUserNameException, Artech.Mvc.ExceptionHandling"
         postHandlingAction="None">
        <exceptionHandlers>
         <add name="ErrorMessageSettingHandler"
           type="Artech.Mvc.ExceptionHandling.ErrorMessageSettingHandler, Artech.Mvc.ExceptionHandling"
           errorMessage="User name does not exist!"/>
       </exceptionHandlers>
      </add>
      <add name="UserNamePasswordNotMatchException" 
          type="Artech.Mvc.ExceptionHandling.Models.UserNamePasswordNotMatchException, Artech.Mvc.ExceptionHandling"
         postHandlingAction="None">
       <exceptionHandlers>
        <add name="ErrorMessageSettingHandler"
           type="Artech.Mvc.ExceptionHandling.ErrorMessageSettingHandler, Artech.Mvc.ExceptionHandling"
           errorMessage="User name does not match password!"/>
       </exceptionHandlers>
      </add>     
     </exceptionTypes>
    </add>
   </exceptionPolicies>
  </exceptionHandling>

現(xiàn)在我們通過路由映射將AccountController和Sign設(shè)置為默認Controller和Action后,開啟我們的應(yīng)用程序。在輸入錯誤的用戶名和錯誤明碼的情況下在ValidationSummary中將自動得到相應(yīng)的錯誤消息。

ASP.NET MVC對異常進行處理的

三、通過配置的Error View處理異常

在上面的配置中,針對InvalidUserNameException和UserNamePasswordNotMatchException這兩種異常類型的配置策略都將PostHandlingAction屬性設(shè)置為“None”,意味著不會將原來的異常和處理后的異常進行重新拋出?,F(xiàn)在我們將該屬性設(shè)置為“ThrowNewException”,意味著我們會將處理后的異常重新拋出來。

  <exceptionHandling>
    <exceptionPolicies>
     <add name="myPolicy">
      <exceptionTypes>
       <add name="InvalidUserNameException" type="Artech.Mvc.ExceptionHandling.Models.InvalidUserNameException, Artech.Mvc.ExceptionHandling"
         postHandlingAction="ThrowNewException">
       ...
       <add name="UserNamePasswordNotMatchException" type="Artech.Mvc.ExceptionHandling.Models.UserNamePasswordNotMatchException, Artech.Mvc.ExceptionHandling"
         postHandlingAction="ThrowNewException">
       ...
      </add>     
     </exceptionTypes>
    </add>
   </exceptionPolicies>
  </exceptionHandling>

按照我們上面的異常處理策略,在這種情況下我們將采用“錯誤頁面”的方式來進行異常處理。也HandleErrorAttribute的處理方式類似,我們支持異常類型和Error View之間的匹配關(guān)系,而這是通過類似于如下的配置來定義的。值得一提的是,這里的異常類型是經(jīng)過處理后重新拋出的異常。

  <artech.exceptionHandling>
    <add exceptionType="Artech.Mvc.ExceptionHandling.Models.InvalidUserNameException, Artech.Mvc.ExceptionHandling"
       errorView="InvalideUserNameError"/>
    <add exceptionType="Artech.Mvc.ExceptionHandling.Models.UserNamePasswordNotMatchException, Artech.Mvc.ExceptionHandling"
       errorView="UserNamePasswordNotMatchError"/>
   </artech.exceptionHandling>

如上面的配置所示,我們?yōu)镮nvalidUserNameException和UserNamePasswordNotMatchException這兩種異常類型定義了不同的Error View,分別是“InvalideUserNameError”和“UserNamePasswordNotMatchError”,詳細定義如下所示:

  @{
     Layout = null;
   }
   <!DOCTYPE html>
   <html>
   <head>
     <title>Error</title>
   </head>
   <body>
    <p style="colorRed; font-weightbold">Sorry,the user name you specify does not exist!</p>
  </body>
  </html>
   
  @{
    Layout = null;
  }
  <!DOCTYPE html>
  <html>
  <head>
    <title>Error</title>
  </head>
  <body>
    <p style="colorRed; font-weightbold">Sorry, The password does not match the given user name!</p>
  </body>
  </html>

現(xiàn)在我們按照上面的方式運行我們的程序,在分別輸入錯誤的用戶名和密碼的情況下會自動顯現(xiàn)相應(yīng)的錯誤頁面。

ASP.NET MVC對異常進行處理的

四、自定義ActionInvoker:ExceptionActionInvoker

對于上述的兩種不同的異常處理方式最終是通過自定義的ActionInvoker來實現(xiàn)的,我們將其命名為ExceptionActionInvoker。如下面的代碼片斷所式,ExceptionActionInvoker直接繼承自ControllerActionInvoker。屬性ExceptionPolicy是一個基于指定的異常策略名稱創(chuàng)建的ExceptionPolicyImpl 對象,用于針對EntLib進行的異常處理。而屬性GetErrorView是一個用于獲得作為錯誤頁面的ViewResult對象的委托。整個異常處理的核心定義在InvokeAction方法中,該方法中指定的handleErrorActionName參數(shù)代表的是“異常處理操作名稱”,整個方法就是按照上述的異常處理策略實現(xiàn)的。

  using System;
   using System.Collections.Generic;
   using System.Linq;
   using System.Web;
   using System.Web.Mvc;
   using Artech.Mvc.ExceptionHandling.Configuration;
   using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
   using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling;
   namespace Artech.Mvc.ExceptionHandling
  {
    public class ExceptionActionInvoker ControllerActionInvoker
    {
      protected ExceptionHandlingSettings ExceptionHandlingSettings{get; private set;}
      protected virtual Func<string, HandleErrorInfo, ViewResult> GetErrorView { get; private set; }
      public ExceptionPolicyImpl ExceptionPolicy { get; private set; }
      public ExceptionActionInvoker(string exceptionPolicy,Func<string, HandleErrorInfo, ViewResult> getErrorView)
      {
        this.ExceptionPolicy = EnterpriseLibraryContainer.Current.GetInstance<ExceptionPolicyImpl>(exceptionPolicy);
        this.GetErrorView = getErrorView;
        this.ExceptionHandlingSettings = ExceptionHandlingSettings.GetSection();
      }
   
      public override bool InvokeAction(ControllerContext controllerContext, string handleErrorActionName)
      {
        ExceptionContext exceptionContext = controllerContext as ExceptionContext;
        if (null == exceptionContext)
        {
          throw new ArgumentException("The controllerContext must be ExceptionContext!", "controllerContext");
        }
        try
        {
          exceptionContext.ExceptionHandled = true;
          if (this.ExceptionPolicy.HandleException(exceptionContext.Exception))
          {
            HandleRethrownException(exceptionContext);
          }
          else
          {
            if (ExceptionHandlingContext.Current.Errors.Count == 0)
            {
              ExceptionHandlingContext.Current.Errors.Add(exceptionContext.Exception.Message);
            }
            ControllerDescriptor controllerDescriptor = this.GetControllerDescriptor(exceptionContext);
            ActionDescriptor handleErrorAction = FindAction(exceptionContext, controllerDescriptor, handleErrorActionName);
            if (null != handleErrorAction)
            {
              IDictionary<string, object> parameters = GetParameterValues(controllerContext, handleErrorAction);
              exceptionContext.Result = this.InvokeActionMethod(exceptionContext, handleErrorAction, parameters);
            }
            else
            {
              HandleRethrownException(exceptionContext);
            }
          }
          return true;
        }
        catch (Exception ex)
        {
          exceptionContext.Exception = ex;
          HandleRethrownException(exceptionContext);
          return true;
        }
      }
      protected virtual void HandleRethrownException(ExceptionContext exceptionContext)
      {
        string errorViewName = this.GetErrorViewName(exceptionContext.Exception.GetType());
        string controllerName = (string)exceptionContext.RouteData.GetRequiredString("controller");
        string action = (string)exceptionContext.RouteData.GetRequiredString("action");
        HandleErrorInfo handleErrorInfo = new HandleErrorInfo(exceptionContext.Exception, controllerName, action);
        exceptionContext.Result = this.GetErrorView(errorViewName, handleErrorInfo);
      }
      protected string GetErrorViewName(Type exceptionType)
      {
        ExceptionErrorViewElement element = ExceptionHandlingSettings.ExceptionErrorViews
          .Cast<ExceptionErrorViewElement>().FirstOrDefault(el=>el.ExceptionType == exceptionType);
        if(null != element)
        {
          return element.ErrorView;
        }
        if(null== element && null != exceptionType.BaseType!= null)
        {
          return GetErrorViewName(exceptionType.BaseType);
        }
        else
        {
          return "Error";
        }
      }
    }
  }

五、自定義Controller:BaseController

ExceptionActionInvoker最終在我們自定義的Controller基類BaseController中被調(diào)用的。ExceptionActionInvoker對象在構(gòu)造函數(shù)中被初始化,并在重寫的OnException方法中被調(diào)用。

  using System;
   using System.Web.Mvc;
   namespace Artech.Mvc.ExceptionHandling
   {
     public abstract class BaseController Controller
     {
       public BaseController(string exceptionPolicy)
       {
         Func<string, HandleErrorInfo, ViewResult> getErrorView = (viewName, handleErrorInfo) => this.View(viewName, handleErrorInfo);
        this.ExceptionActionInvoker = new ExceptionActionInvoker(exceptionPolicy,getErrorView);
      }
      public BaseController(ExceptionActionInvoker actionInvoker)
      {
        this.ExceptionActionInvoker = actionInvoker;
      }
   
      public virtual ExceptionActionInvoker ExceptionActionInvoker { get; private set; }
   
      protected virtual string GetHandleErrorActionName(string actionName)
      {
        return string.Format("On{0}Error", actionName);
      }
   
      protected override void OnException(ExceptionContext filterContext)
      {
        using (ExceptionHandlingContextScope contextScope = new ExceptionHandlingContextScope(filterContext))
        {
          string actionName = RouteData.GetRequiredString("action");
          string handleErrorActionName = this.GetHandleErrorActionName(actionName);
          this.ExceptionActionInvoker.InvokeAction(filterContext, handleErrorActionName);
          foreach (var error in ExceptionHandlingContext.Current.Errors)
          {
            ModelState.AddModelError(Guid.NewGuid().ToString() ,error.ErrorMessage);
          }
        }
      }
    }
  }

值得一提的是:整個OnException方法中的操作都在一個ExceptionHandlingContextScope中進行的。顧名思義, 我們通過ExceptionHandlingContextScope為ExceptionHandlingContext創(chuàng)建了一個范圍。ExceptionHandlingContext定義如下,我們可以通過它獲得當前的ExceptionContext和ModelErrorCollection,而靜態(tài)屬性Current返回當前的ExceptionHandlingContext對象。

  public class ExceptionHandlingContext
   {
     [ThreadStatic]
     private static ExceptionHandlingContext current;
   
     public ExceptionContext ExceptionContext { get; private set; }
     public ModelErrorCollection Errors { get; private set; }
   
     public ExceptionHandlingContext(ExceptionContext exceptionContext)
    {
      this.ExceptionContext = exceptionContext;
      this.Errors = new ModelErrorCollection();
    }
    public static ExceptionHandlingContext Current
    {
      get { return current; }
      set { current = value; }
    }
  }

在BaseController的OnException方法中,當執(zhí)行了ExceptionActionInvoker的InvokeAction之后,我們會將當前ExceptionHandlingContext的ModelError轉(zhuǎn)移到當前的ModelState中。這就是為什么我們會通過ValidationSummary顯示錯誤信息的原因。對于我們的例子來說,錯誤消息的指定是通過如下所示的ErrorMessageSettingHandler 實現(xiàn)的,而它僅僅將指定的錯誤消息添加到當前ExceptionHandlingContext的Errors屬性集合中而已。

  [ConfigurationElementType(typeof(ErrorMessageSettingHandlerData))]
   public class ErrorMessageSettingHandler IExceptionHandler
   {
     public string ErrorMessage { get; private set; }
     public ErrorMessageSettingHandler(string errorMessage)
     {
       thisErrorMessage = errorMessage;
     }
     public Exception HandleException(Exception exception, Guid handlingInstanceId)
    {
      if (null == ExceptionHandlingContextCurrent)
      {
        throw new InvalidOperationException("");
      }
   
      if (stringIsNullOrEmpty(thisErrorMessage))
      {
        ExceptionHandlingContextCurrentErrorsAdd(exceptionMessage);
      }
      else
      {
        ExceptionHandlingContextCurrentErrorsAdd(thisErrorMessage);
      }
      return exception;
    }
  }

以上是ASP.NET MVC對異常進行處理的的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

文章名稱:ASP.NETMVC對異常進行處理的-創(chuàng)新互聯(lián)
網(wǎng)頁路徑:http://aaarwkj.com/article20/cchico.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、ChatGPT、做網(wǎng)站電子商務(wù)、搜索引擎優(yōu)化、商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設(shè)
免费在线一区二区av| 熟女少妇a一区二区三区| 久草午夜福利视频免费观看| 婷婷五激情五月激情片| 日本韩国一级黄色免费| 成年人免费国产视频网站| 高潮内射主播自拍一区| 视频免费观看网站不卡| av天堂精品一区二区三区| 欧美口爆吞精在线观看| 狠狠躁夜夜躁人人爽蜜桃| 五月婷婷六月丁香伊人妞| 亚洲福利网址一二三区| 亚洲另类偷拍校园伦理| 亚洲熟妇av乱码在线| 熟女人妻一区二区三区免费看| 色综合色综合色综合色综合| 成年人免费久久毛片| 久久精品91久久久| 岛国大片一区二区三区| 亚洲经典日韩欧美一区| 欧美视频亚洲视频自拍视频| 精品av一区二区在线| 国产高潮精品呻吟久久av| 免费高清视频一区二区在线观看| 91久久精品中文字幕| 一区二区亚洲成人精品| 91久久精品国产一区| 色婷婷国产精品高潮呻吟| 天天操天天日天天射夜夜爽| 久久 久久国内精品亚洲| 日韩欧美一区二区麻豆| 成人午夜黄色福利视频| 欧美精品欧美精品一区二区 | 国产亚洲日本一区二区三区| 永久黄区观看在线网址| 亚洲一区二区三区 码| 亚洲精品a在线观看av| 中文字慕日韩精品欧美一区| 国产精品久久护士96| 久久精品亚洲国产成人av|