Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

The solution of ASP.NET MVC based on exception handling

2025-02-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

Today, I will talk to you about the solution of ASP.NET MVC based on exception handling, which may not be well understood by many people. in order to make you understand better, the editor has summarized the following for you. I hope you can get something from this article.

EntLib's exception handling application block (Exception Handling Application Block) is a good exception handling framework, which allows us to define exception handling strategies in a configured way. ASP.NET MVC is an extensible development framework. In this article, I will integrate with EntLib through its extension and provide a complete exception handling solution.

I. basic exception handling strategy

Let's first discuss the specific exception handling strategy adopted by our solution:

We will handle the exception thrown by one of the Action methods of Controller in accordance with the specified configuration policy. We can adopt the common methods of exception handling such as logging, exception replacement and encapsulation.

For handled exceptions, if the exception handling policy specifies that they need to be thrown, they are automatically redirected to the error page that matches the exception type. We will maintain a matching relationship between exception types and Error View

For the handled exception, if the exception handling policy states that it is not necessary to throw it, an error handling Action matching the current Action operation will be executed to handle it. The exception handling Action method defaults to the naming convention of "On {Action} Error", and the current context is bound to the parameters of the exception handling operation method. Except for the second time, we will set the error message for the current ModelState

If the user has not defined the corresponding exception handling Action, the "error page redirection" method is still used for exception handling.

Second, handle exceptions through custom Action

In order to give readers a deep understanding of the exception handling page introduced above, let's give an example demonstration. This example is used to simulate user login, and we define the following Model:LoginInfoModel that contains only two attributes: user name and password.

NamespaceArtech.Mvc.ExceptionHandling.Models {publicclassLoginInfo {[Display (Name = "User Name")] [Required (ErrorMessage = "User Name is manadatory!")] PublicstringUserName {get; set;} [Display (Name = "Password")] [DataType (DataType.Password)] [Required (ErrorMessage = "Password is manadatory!")] PublicstringPassword {get; set;}

We define the following AccountController, which is a subclass of our custom BaseController. At construction time, AccountController calls the parameters specified by the base class constructor to represent the configuration name of the exception handling policy. The SignIn method represents the operation used to "log in", and OnSignInError represents the exception handling operation corresponding to that operation. If the exception thrown in the SignIn operation is handled and no longer needs to be thrown, it will be called OnSignInError, and the ModelState has been set the corresponding error message.

PublicclassAccountController: BaseController {publicAccountController () base ("myPolicy") 5: {} publicActionResult SignIn () {returnView (newLoginInfo ());} [HttpPost] publicActionResult SignIn (LoginInfo loginInfo) {if (! ModelState.IsValid) {returnthis.View (newLoginInfo {UserName = loginInfo.UserName});} if (loginInfo.UserName! = "Foo") {thrownewInvalidUserNameException ();} if (loginInfo.Password! = "password") {thrownewUserNamePasswordNotMatchException ();} ViewBag.Message = "Authentication Succeeds!" Returnthis.View (newLoginInfo {UserName = loginInfo.UserName});} publicActionResult OnSignInError (stringuserName) {returnthis.View (newLoginInfo {UserName = userName});}}

The authentication logic defined in the SignIn operation method looks like this: if the user name is not "Foo", an InvalidUserNameException exception is thrown; if the password is not "password", an UserNamePasswordNotMatchException exception is thrown. Here is the definition of the View corresponding to the SignIn operation:

Model Artech.Mvc.ExceptionHandling.Models.LoginInfo @ {ViewBag.Title = "SignIn";} @ Html.ValidationSummary () @ if (ViewBag.Messages! = null) {@ ViewBag.Messages} @ using (Html.BeginForm ()) {@ Html.EditorForModel ()}

The exception handling policy "myPolicy" specified during AccountController initialization is defined in the following configuration. We specifically deal with the InvalidUserNameException and UserNamePasswordNotMatchException thrown by the SignIn operation method, while ErrorMessageSettingHandler is our custom exception handler, which is only used to set error messages. As the following code snippet shows, if the above two types of exceptions are thrown, the final error message will be specified as "User name does not exist!" And "User name does not match password!"

Now that we have set AccountController and Sign as the default Controller and Action through the route map, open our application. If you enter the wrong user name and error code, you will automatically get the corresponding error message in ValidationSummary.

Third, handle exceptions through the configured Error View

In the above configuration, the configuration policy for both InvalidUserNameException and UserNamePasswordNotMatchException exception types sets the PostHandlingAction property to "None", which means that the original and handled exceptions are not re-thrown. Now we set this property to "ThrowNewException", which means that we will rethrow the handled exception.

......

In accordance with our above exception handling strategy, in this case we will use the "error page" approach to exception handling. HandleErrorAttribute is also handled in a similar way, we support the matching relationship between exception types and Error View, which is defined by a configuration similar to the following. It is worth mentioning that the exception type here is the exception that is rethrown after handling.

......

As shown in the above configuration, we have defined different Error View for the two exception types, InvalidUserNameException and UserNamePasswordNotMatchException, which are "InvalideUserNameError" and "UserNamePasswordNotMatchError", respectively. The detailed definition is as follows:

@ {Layout = null;} Error Sorry,the user name you specify does not exist!

@ {Layout = null;} Error Sorry, The password does not match the given user name!

Now we run our program as above, and the corresponding error page will be automatically displayed if we enter the wrong user name and password respectively.

IV. Custom ActionInvoker:ExceptionActionInvoker

The above two different exception handling methods are finally implemented through a custom ActionInvoker, and we name it ExceptionActionInvoker. As the following code snippet shows, ExceptionActionInvoker inherits directly from ControllerActionInvoker. The property ExceptionPolicy is an ExceptionPolicyImpl object created based on the specified exception policy name for exception handling against EntLib. The property GetErrorView is a delegate used to get the ViewResult object as the error page. The core of the whole exception handling is defined in the InvokeAction method, and the handleErrorActionName parameter specified in this method represents the "exception handling operation name". The whole method is implemented in accordance with the above exception handling strategy.

UsingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Web; usingSystem.Web.Mvc; usingArtech.Mvc.ExceptionHandling.Configuration; usingMicrosoft.Practices.EnterpriseLibrary.Common.Configuration; usingMicrosoft.Practices.EnterpriseLibrary.ExceptionHandling; namespaceArtech.Mvc.ExceptionHandling {publicclassExceptionActionInvoker: ControllerActionInvoker {protectedExceptionHandlingSettings ExceptionHandlingSettings {get; privateset;} protectedvirtualFunc GetErrorView {get; privateset;} publicExceptionPolicyImpl ExceptionPolicy {get; privateset;} publicExceptionActionInvoker (stringexceptionPolicy,Func getErrorView) {this.ExceptionPolicy = EnterpriseLibraryContainer.Current.GetInstance (exceptionPolicy); this.GetErrorView = getErrorView This.ExceptionHandlingSettings = ExceptionHandlingSettings.GetSection ();} publicoverrideboolInvokeAction (ControllerContext controllerContext, stringhandleErrorActionName) {ExceptionContext exceptionContext = controllerContext asExceptionContext; if (null== exceptionContext) {thrownewArgumentException ("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) {IDictionaryparameters = GetParameterValues (controllerContext, handleErrorAction); exceptionContext.Result = this.InvokeActionMethod (exceptionContext, handleErrorAction, parameters);} else {HandleRethrownException (exceptionContext);}} returntrue;} catch (Exception ex) {exceptionContext.Exception = ex;60:HandleRethrownException (exceptionContext); returntrue } protectedvirtualvoidHandleRethrownException (ExceptionContext exceptionContext) {stringerrorViewName = this.GetErrorViewName (exceptionContext.Exception.GetType ()); stringcontrollerName = (string) exceptionContext.RouteData.GetRequiredString ("controller"); stringaction = (string) exceptionContext.RouteData.GetRequiredString ("action"); HandleErrorInfo handleErrorInfo = newHandleErrorInfo (exceptionContext.Exception, controllerName, action); 70:exceptionContext.Result = this.GetErrorView (errorViewName, handleErrorInfo);} protectedstringGetErrorViewName (Type exceptionType) {ExceptionErrorViewElement element = ExceptionHandlingSettings.ExceptionErrorViews75:.Cast (). FirstOrDefault (el= > el.ExceptionType = = exceptionType) If (nulls = element) {returnelement.ErrorView;} if (null== element & & nullboxes = substitutionType.BaseTypeType = null) {returnGetErrorViewName (exceptionType.BaseType);} else {return "Error";}

5. Custom Controller:BaseController

ExceptionActionInvoker is finally called in our custom Controller base class BaseController. The ExceptionActionInvoker object is initialized in the constructor and called in the overridden OnException method.

UsingSystem; usingSystem.Web.Mvc; namespaceArtech.Mvc.ExceptionHandling {publicabstractclassBaseController: Controller {publicBaseController (stringexceptionPolicy) {Func getErrorView = (viewName, handleErrorInfo) = > this.View (viewName, handleErrorInfo); this.ExceptionActionInvoker = newExceptionActionInvoker (exceptionPolicy,getErrorView);} publicBaseController (ExceptionActionInvoker actionInvoker) {this.ExceptionActionInvoker = actionInvoker;} publicvirtualExceptionActionInvoker ExceptionActionInvoker {get; privateset;} protectedvirtualstringGetHandleErrorActionName (stringactionName) {returnstring.Format ("On {0} Error", actionName) } protectedoverridevoidOnException (ExceptionContext filterContext) {using (ExceptionHandlingContextScope contextScope = newExceptionHandlingContextScope (filterContext)) {stringactionName = RouteData.GetRequiredString ("action"); stringhandleErrorActionName = this.GetHandleErrorActionName (actionName); this.ExceptionActionInvoker.InvokeAction (filterContext, handleErrorActionName); foreach (var error inExceptionHandlingContext.Current.Errors) {ModelState.AddModelError (Guid.NewGuid (). ToString (), error.ErrorMessage);}

It is worth mentioning that the operations in the entire OnException method are done in one ExceptionHandlingContextScope. As the name implies, we created a scope for ExceptionHandlingContext through ExceptionHandlingContextScope. ExceptionHandlingContext is defined as follows, through which we can get the current ExceptionContext and ModelErrorCollection, while the static property Current returns the current ExceptionHandlingContext object.

PublicclassExceptionHandlingContext {[ThreadStatic] privatestaticExceptionHandlingContext current; publicExceptionContext ExceptionContext {get; privateset;} publicModelErrorCollection Errors {get; privateset;} publicExceptionHandlingContext (ExceptionContext exceptionContext) {this.ExceptionContext = exceptionContext;this.Errors = newModelErrorCollection ();} publicstaticExceptionHandlingContext Current {get {returncurrent;} set {current = value;}

In the OnException method of BaseController, when the InvokeAction of ExceptionActionInvoker is executed, we transfer the ModelError of the current ExceptionHandlingContext to the current ModelState. This is why we display error messages through ValidationSummary. For our example, the error message is specified through the ErrorMessageSettingHandler shown below, which simply adds the specified error message to the Errors property collection of the current ExceptionHandlingContext.

[ConfigurationElementType (typeof (ErrorMessageSettingHandlerData))] publicclassErrorMessageSettingHandler: IExceptionHandler {publicstringErrorMessage {get; privateset;} publicErrorMessageSettingHandler (stringerrorMessage) {this.ErrorMessage = errorMessage;} publicException HandleException (Exception exception, Guid handlingInstanceId) {if (null== ExceptionHandlingContext.Current) {thrownewInvalidOperationException ("...");} if (string.IsNullOrEmpty (this.ErrorMessage)) {ExceptionHandlingContext.Current.Errors.Add (exception.Message);} else {ExceptionHandlingContext.Current.Errors.Add (this.ErrorMessage);} returnexception }} after reading the above, do you have any further understanding of ASP.NET MVC's exception handling-based solution? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report