日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
ASP.NETMVC基于異常處理的解決方案

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

成都創(chuàng)新互聯(lián)服務(wù)項目包括宣城網(wǎng)站建設(shè)、宣城網(wǎng)站制作、宣城網(wǎng)頁制作以及宣城網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,宣城網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到宣城省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

目錄

  一、基本異常處理策略

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

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

  四、自定義ActionInvoker:ExceptionActionInvoker

  五、自定義Controller:BaseController

  一、基本異常處理策略

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

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

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

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

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

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

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

 
 
 
 
  1. namespaceArtech.Mvc.ExceptionHandling.Models
  2. {
  3. publicclassLoginInfo
  4. {
  5. [Display(Name ="User Name")]
  6. [Required(ErrorMessage = "User Name is manadatory!")]
  7. publicstringUserName { get; set; }
  8. [Display(Name = "Password")]
  9. [DataType(DataType.Password)]
  10. [Required(ErrorMessage = "Password is manadatory!")]
  11. publicstringPassword { get; set; }
  12. }
  13. }

  我們定義了如下一個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)的錯誤消息。

 
 
 
 
  1. publicclassAccountController : BaseController
  2. {
  3. publicAccountController()
  4.  base("myPolicy")5:{ }
  5. publicActionResult SignIn()
  6. {
  7. returnView(newLoginInfo());
  8. }
  9. [HttpPost]
  10. publicActionResult SignIn(LoginInfo loginInfo)
  11. {
  12. if(!ModelState.IsValid)
  13. {
  14. returnthis.View(newLoginInfo { UserName = loginInfo.UserName });
  15. }
  16. if(loginInfo.UserName != "Foo")
  17. {
  18. thrownewInvalidUserNameException();
  19. }
  20. if(loginInfo.Password != "password")
  21. {
  22. thrownewUserNamePasswordNotMatchException();
  23. }
  24. ViewBag.Message = "Authentication Succeeds!";
  25. returnthis.View(newLoginInfo { UserName = loginInfo.UserName });
  26. }
  27. publicActionResult OnSignInError(stringuserName)
  28. {
  29. returnthis.View(newLoginInfo { UserName = userName });
  30. }
  31. }

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

 
 
 
 
  1. @model Artech.Mvc.ExceptionHandling.Models.LoginInfo
  2. @{
  3. ViewBag.Title = "SignIn";
  4. }
  5. @Html.ValidationSummary()
  6. @if (ViewBag.Messages != null)
  7. @ViewBag.Messages
  8. }
  9. @using (Html.BeginForm())
  10. @Html.EditorForModel()
  11. }

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

 
 
 
 
  1. type="Artech.Mvc.ExceptionHandling.Models.InvalidUserNameException, Artech.Mvc.ExceptionHandling"
  2. postHandlingAction="None">
  3. type="Artech.Mvc.ExceptionHandling.ErrorMessageSettingHandler, Artech.Mvc.ExceptionHandling"
  4. errorMessage="User name does not exist!"/>
  5. type="Artech.Mvc.ExceptionHandling.Models.UserNamePasswordNotMatchException, Artech.Mvc.ExceptionHandling"
  6. postHandlingAction="None">
  7. type="Artech.Mvc.ExceptionHandling.ErrorMessageSettingHandler, Artech.Mvc.ExceptionHandling"
  8. errorMessage="User name does not match password!"/>

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

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

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

 
 
 
 
  1. postHandlingAction="ThrowNewException">
  2. ...
  3. ...

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

 
 
 
 
  1. postHandlingAction="ThrowNewException">
  2. ...
  3. ...

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

 
 
 
 
  1. @{
  2. Layout = null;
  3. }
  4. Error
  5. Sorry,the user name you specify does not exist!

  6.  @{
  7. Layout = null;
  8. }
  9. Error
  10. Sorry, The password does not match the given user name!

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

四、自定義ActionInvoker:ExceptionActionInvoker

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

 
 
 
 
  1. usingSystem;
  2. usingSystem.Collections.Generic;
  3. usingSystem.Linq;
  4. usingSystem.Web;
  5. usingSystem.Web.Mvc;
  6. usingArtech.Mvc.ExceptionHandling.Configuration;
  7. usingMicrosoft.Practices.EnterpriseLibrary.Common.Configuration;
  8. usingMicrosoft.Practices.EnterpriseLibrary.ExceptionHandling;
  9. namespaceArtech.Mvc.ExceptionHandling
  10. {
  11. publicclassExceptionActionInvoker: ControllerActionInvoker
  12. {
  13. protectedExceptionHandlingSettings ExceptionHandlingSettings{get; privateset;}
  14. protectedvirtualFunc GetErrorView { get; privateset; }
  15. publicExceptionPolicyImpl ExceptionPolicy { get; privateset; }
  16. publicExceptionActionInvoker(stringexceptionPolicy,Func getErrorView)
  17. {
  18. this.ExceptionPolicy = EnterpriseLibraryContainer.Current.GetInstance(exceptionPolicy);
  19. this.GetErrorView = getErrorView;
  20. this.ExceptionHandlingSettings = ExceptionHandlingSettings.GetSection();
  21. }
  22. publicoverrideboolInvokeAction(ControllerContext controllerContext, stringhandleErrorActionName)
  23. {
  24. ExceptionContext exceptionContext = controllerContext asExceptionContext;
  25. if(null== exceptionContext)
  26. {
  27. thrownewArgumentException("The controllerContext must be ExceptionContext!", "controllerContext");
  28. }
  29. try
  30. {
  31. exceptionContext.ExceptionHandled = true;
  32. if(this.ExceptionPolicy.HandleException(exceptionContext.Exception))
  33. {
  34. HandleRethrownException(exceptionContext);
  35. }
  36. else
  37. {
  38. if(ExceptionHandlingContext.Current.Errors.Count == 0)
  39. {
  40. ExceptionHandlingContext.Current.Errors.Add(exceptionContext.Exception.Message);
  41. }
  42. ControllerDescriptor controllerDescriptor = this.GetControllerDescriptor(exceptionContext);
  43. ActionDescriptor handleErrorAction = FindAction(exceptionContext, controllerDescriptor, handleErrorActionName);
  44. if(null!= handleErrorAction)
  45. {
  46. IDictionaryparameters = GetParameterValues(controllerContext, handleErrorAction);
  47. exceptionContext.Result = this.InvokeActionMethod(exceptionContext, handleErrorAction, parameters);
  48. }
  49. else
  50. {
  51. HandleRethrownException(exceptionContext);
  52. }
  53. }
  54. returntrue;
  55. }
  56. catch(Exception ex)
  57. {
  58. exceptionContext.Exception = ex;60:HandleRethrownException(exceptionContext);
  59. returntrue;
  60. }
  61. }
  62. protectedvirtualvoidHandleRethrownException(ExceptionContext exceptionContext)
  63. {
  64. stringerrorViewName = this.GetErrorViewName(exceptionContext.Exception.GetType());
  65. stringcontrollerName = (string)exceptionContext.RouteData.GetRequiredString("controller");
  66. stringaction = (string)exceptionContext.RouteData.GetRequiredString("action");
  67. HandleErrorInfo handleErrorInfo = newHandleErrorInfo(exceptionContext.Exception, controllerName, action);70:exceptionContext.Result = this.GetErrorView(errorViewName, handleErrorInfo);
  68. }
  69. protectedstringGetErrorViewName(Type exceptionType)
  70. {
  71. ExceptionErrorViewElement element = ExceptionHandlingSettings.ExceptionErrorViews75:.Cast().FirstOrDefault(el=>el.ExceptionType == exceptionType);
  72. if(null!= element)
  73. {
  74. returnelement.ErrorView;
  75. }
  76. if(null== element &&null!= exceptionType.BaseType!= null)
  77. {
  78. returnGetErrorViewName(exceptionType.BaseType);
  79. }
  80. else
  81. {
  82. return"Error";
  83. }
  84. }
  85. }
  86. }

  五、自定義Controller:BaseController

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

 
 
 
 
  1. usingSystem;
  2. usingSystem.Web.Mvc;
  3. namespaceArtech.Mvc.ExceptionHandling
  4. {
  5. publicabstractclassBaseController : Controller
  6. {
  7. publicBaseController(stringexceptionPolicy)
  8. {
  9. Func getErrorView = (viewName, handleErrorInfo) => this.View(viewName, handleErrorInfo);
  10. this.ExceptionActionInvoker = newExceptionActionInvoker(exceptionPolicy,getErrorView);
  11. }
  12. publicBaseController(ExceptionActionInvoker actionInvoker)
  13. {
  14. this.ExceptionActionInvoker = actionInvoker;
  15. }
  16. publicvirtualExceptionActionInvoker ExceptionActionInvoker { get; privateset; }
  17. protectedvirtualstringGetHandleErrorActionName(stringactionName)
  18. {
  19. returnstring.Format("On{0}Error", actionName);
  20. }
  21. protectedoverridevoidOnException(ExceptionContext filterContext)
  22. {
  23. using(ExceptionHandlingContextScope contextScope = newExceptionHandlingContextScope(filterContext))
  24. {
  25. stringactionName = RouteData.GetRequiredString("action");
  26. stringhandleErrorActionName = this.GetHandleErrorActionName(actionName);
  27. this.ExceptionActionInvoker.InvokeAction(filterContext, handleErrorActionName);
  28. foreach(var error inExceptionHandlingContext.Current.Errors)
  29. {
  30. ModelState.AddModelError(Guid.NewGuid().ToString() ,error.ErrorMessage);
  31. }
  32. }
  33. }
  34. }
  35. }

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

 
 
 
 
  1. publicclassExceptionHandlingContext
  2. {
  3. [ThreadStatic]
  4. privatestaticExceptionHandlingContext current;
  5. publicExceptionContext ExceptionContext { get; privateset; }
  6. publicModelErrorCollection Errors { get; privateset; }
  7. publicExceptionHandlingContext(ExceptionContext exceptionContext)
  8. {
  9. this.ExceptionContext = exceptionContext;
  10. this.Errors = newModelErrorCollection();
  11. }
  12. publicstaticExceptionHandlingContext Current
  13. {
  14. get { returncurrent; }
  15. set { current = value;}
  16. }
  17. }

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

 
 
 
 
  1. [ConfigurationElementType(typeof(ErrorMessageSettingHandlerData))]
  2. publicclassErrorMessageSettingHandler : IExceptionHandler
  3. {
  4. publicstringErrorMessage { get; privateset; }
  5. publicErrorMessageSettingHandler(stringerrorMessage)
  6. {
  7. this.ErrorMessage = errorMessage;
  8. }
  9. publicException HandleException(Exception exception, Guid handlingInstanceId)
  10. {
  11. if(null== ExceptionHandlingContext.Current)
  12. {
  13. thrownewInvalidOperationException("...");
  14. }
  15. if(string.IsNullOrEmpty(this.ErrorMessage))
  16. {
  17. ExceptionHandlingContext.Current.Errors.Add(exception.Message);
  18. }
  19. else
  20. {
  21. ExceptionHandlingContext.Current.Errors.Add(this.ErrorMessage);
  22. }
  23. returnexception;
  24. }
  25. }

當(dāng)前標(biāo)題:ASP.NETMVC基于異常處理的解決方案
分享網(wǎng)址:http://www.5511xx.com/article/ccohpcd.html