加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

ASP.NET MVC集成EntLib实现“自动化”异常处理[实现篇]

发布时间:2020-12-16 09:05:18 所属栏目:asp.Net 来源:网络整理
导读:通过《实例篇》的实演示可以看出我们通过扩展实现的自动异常处理机制能够利用EntLib的EHAB根据执行的一场处理策略对某个Action方法执行过程中抛出的异常进行处理。对于处理后的结果,则按照如下的机制对请求进行响应。[源代码从这里下载][本文已经同步到《Ho

通过《实例篇》的实演示可以看出我们通过扩展实现的自动异常处理机制能够利用EntLib的EHAB根据执行的一场处理策略对某个Action方法执行过程中抛出的异常进行处理。对于处理后的结果,则按照如下的机制对请求进行响应。[源代码从这里下载][本文已经同步到《How ASP.NET MVC Works?》中]

  • 对于Ajax请求,直接创建一个用于封装被处理后异常的数据对象,并据此创建一个JsonResult将异常信息回复给客户端。
  • 对于非Ajax请求,如果当前Action方法上应用HandleErrorActionAttribute特性设置了匹配的Action方法用于处理该方法抛出的异常,那么执行该方法并用返回的ActionResult对象响应当前请求。
  • 如果HandleErrorActionAttribute特性不曾应用在当前Action方法上,或者通过该特性指定的Action不存在,则将默认的错误View呈现出来作为多请求的响应。

目录
一、ExceptionPolicyAttribute & HandleErrorActionAttribute
二、实现在OnException方法中的异常处理逻辑
三、将处理后的错误消息存放在HttpContext的Items中
四、用于设置错误消息的ErrorMessageHandler

一、ExceptionPolicyAttribute & HandleErrorActionAttribute

所有的这些都是通过一个自定义的ExceptionFilter来实现的。不过我们并没有定义任何的ExceptionFilter特性,而是将异常处理实现在一个自定义的ExtendedController基类中,对异常的自动处理实现在重写的OnException方法中,不过在介绍该方法的逻辑之前我们先来看看定义在ExtendedController中的其他辅助成员。

   1: public class ExtendedController: Controller
   3:     private static Dictionary<Type,ControllerDescriptor> controllerDescriptors = new Dictionary<Type,ControllerDescriptor>();
   5:? 
   7:     {
   9:     }      
  11:     //描述当前Controller的ControllerDescriptor
  13:     {
  15:         {
  17:             if(controllerDescriptors.TryGetValue(this.GetType(),out descriptor))
  19:                 return descriptor;
  21:             lock (syncHelper)
  23:                 if (controllerDescriptors.TryGetValue(  24:                 {
  27:                 else
  29:                     descriptor = new ReflectedControllerDescriptor(this.GetType());
  31:                       32:                 }
  34:         }
  36:     //获取异常处理策略名称
  38:     {
  40:         ActionDescriptor actionDescriptor = this.Descriptor.FindAction(ControllerContext,actionName);
  42:         {
  44:         }
  46:            Descriptor.GetCustomAttributes(true).OfType<ExceptionPolicyAttribute>().FirstOrDefault()?? new ExceptionPolicyAttribute("");
  48:     }
  50:     //获取Handle-Error-Action名称
  52:     {
  57:               58:         }
  60:             Descriptor.GetCustomAttributes(true).OfType<HandleErrorActionAttribute>().FirstOrDefault()?? new HandleErrorActionAttribute(  61:         return handleErrorActionAttribute.HandleErrorAction;
  63:? 
  65:     public HandleErrorActionInvoker HandleErrorActionInvoker { get; private set; }
  67:     public ExtendedController()
  69:         this.HandleErrorActionInvoker = new HandleErrorActionInvoker();
  71: }

ExtendedController的Descriptor属性用于返回描述自身的ControllerDescriptor对象,实际上是一个ReflectedControllerDescriptor对象。为了避免频繁的反射操作造成对性能的影响,我们将基于某个类型解析出来的ReflectedControllerDescriptor对象进行了全局性缓存。

GetExceptionPolicyName方法用于返回当前采用的异常处理策略名称。异常处理策略名称是通过具有如下定义的ExceptionPolicyAttribute特性来指定的。该特性既可以应用在Controller类型上,也可以应用在Action方法上,换句话说,我们可以采用不同的策略来处理从不同Action执行过程中抛出的异常。GetExceptionPolicyName利用ControllerDesctior和ActionDescriptor可以很容易地得到应用的ExceptionPolicyAttribute特性,进而得到相应的异常处理策略名称。

   2: class ExceptionPolicyAttribute: Attribute
string ExceptionPolicyName { get; private set; }
   6:     {
   8:     }
false)]
string HandleErrorAction { get; public HandleErrorActionAttribute(string handleErrorAction = "")
   9: }

通过HandleErrorActionAttribute特性设置的Handle-Error-Action需要手工执行以实现对当前请求的响应,为此我们创建了一个具有如下定义的HandleErrorActionInvoker。它是ControllerActionInvoker的子类,Handle-Error-Action需要手工执行以实现对当前请求的响应的执行通过虚方法InvokeActionMethod来完成。ExtendedController的HandleErrorActionInvoker返回的就是这样一个对象。

virtual ActionResult InvokeActionMethod(ControllerContext controllerContext,ActionDescriptor actionDescriptor)
   5:         IDictionary<string,1)">object> parameterValues = this.GetParameterValues(controllerContext,actionDescriptor);
   7:     }
   2: {    
   5:     {
string exceptionPolicyName = this.GetExceptionPolicyName();
   9:         {
  11:             return;
  13:? 
  15:         filterContext.ExceptionHandled = true;
  17:         string errorMessage;
  19:         {
  21:             errorMessage = System.Web.HttpContext.Current.GetErrorMessage();
  23:         finally
  25:             System.Web.HttpContext.Current.ClearErrorMessage();
  27:         exceptionToThrow = exceptionToThrow ?? filterContext.Exception;
  29:         //对于Ajax请求,直接返回一个用于封装异常的JsonResult
  31:         {
  33:               35:? 
  37:         //否则将Error View呈现出来
string controllerName = ControllerContext.RouteData.GetRequiredString("controller");
  41:         errorMessage = string.IsNullOrEmpty(errorMessage) ? exceptionToThrow.Message : errorMessage;
  43:         {
  46:         else
  48:             ActionDescriptor actionDescriptor = Descriptor.FindAction(ControllerContext,handleErrorAction);                
  50:             filterContext.Result = this.HandleErrorActionInvoker.InvokeActionMethod(ControllerContext,actionDescriptor);
  52:     }      
class HttpContextExtensions
   4:  
   7:         context.Items[keyOfErrorMessage]=errorMessage;
  10:     string GetErrorMessage(this HttpContext context)
  12:         return context.Items[keyOfErrorMessage] as string;
  14:? 
  16:     {
  18:         {
  20:         }            
  22: }

四、用于设置错误消息的ErrorMessageHandler

用于设置错误信息的ErrorMessageHandler以及对应配置元素类型ErrorMessageHandlerData定义如下。ErrorMessageHandler表示错误消息的ErrorMessage属性在构造函数中被初始化,而在实现的HandleException方法中直接通过调用当前HttpContext的扩展方法SetErrorMessage进行错误消息的设置。

class ErrorMessageHandler: IExceptionHandler
   9:     public Exception HandleException(Exception exception,Guid handlingInstanceId)
  11:         null != HttpContext.Current)
  13:             HttpContext.Current.SetErrorMessage(this.ErrorMessage);
  15:         return exception;
  17: }
  19: class ErrorMessageHandlerData : ExceptionHandlerData
  21:     [ConfigurationProperty("errorMessage",IsRequired=  22:     string ErrorMessage
  24:         get { return (string)this["errorMessage"]; }
  26:     }
  28:     override IEnumerable<TypeRegistration> GetRegistrations(string namePrefix)
yield new TypeRegistration<IExceptionHandler>(() => new ErrorMessageHandler(this.ErrorMessage))
  33:             Lifetime = TypeRegistrationLifetime.Transient
  36: }

?

ASP.NET MVC集成EntLib实现“自动化”异常处理[实例篇]
ASP.NET MVC集成EntLib实现“自动化”异常处理[实现篇]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读