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

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

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

一、ExceptionPolicyAttribute & HandleErrorActionAttribute

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

双击代码全选

1

1:publicclass ExtendedController: Controller

 

双击代码全选

1

2: {

 

双击代码全选

1

3:privatestatic Dictionary<Type, ControllerDescriptor> controllerDescriptors = new Dictionary<Type, ControllerDescriptor>();

 

双击代码全选

1

4:privatestaticobject syncHelper = newobject();

 

双击代码全选

1

 

 

双击代码全选

1

6:protectedoverridevoid OnException(ExceptionContext filterContext)

 

双击代码全选

1

7:     {

 

双击代码全选

1

8://省略成员

 

双击代码全选

1

9:     }

 

双击代码全选

1

10:

 

双击代码全选

1

11://描述当前Controller的ControllerDescriptor

 

双击代码全选

1

12:public ControllerDescriptor Descriptor

 

双击代码全选

1

13:     {

 

双击代码全选

1

14:         get

 

双击代码全选

1

15:         {

 

双击代码全选

1

16:             ControllerDescriptor descriptor;

 

双击代码全选

1

17:if(controllerDescriptors.TryGetValue(this.GetType(), out descriptor))

 

双击代码全选

1

18:             {

 

双击代码全选

1

19:return descriptor;

 

双击代码全选

1

20:             }

 

双击代码全选

1

21:lock (syncHelper)

 

双击代码全选

1

22:             {

 

双击代码全选

1

23:if (controllerDescriptors.TryGetValue(this.GetType(), out descriptor))

 

双击代码全选

1

24:                 {

 

双击代码全选

1

25:return descriptor;

 

双击代码全选

1

26:                 }

 

双击代码全选

1

27:else

 

双击代码全选

1

28:                 {

 

双击代码全选

1

29:                     descriptor = new ReflectedControllerDescriptor(this.GetType());

 

双击代码全选

1

30:                     controllerDescriptors.Add(this.GetType(), descriptor);

 

双击代码全选

1

31:return descriptor;

 

双击代码全选

1

32:                 }

 

双击代码全选

1

33:             }

 

双击代码全选

1

34:         }

 

双击代码全选

1

35:     }

 

双击代码全选

1

36://获取异常处理策略名称

 

双击代码全选

1

37:publicstring GetExceptionPolicyName()

 

双击代码全选

1

38:     {

 

双击代码全选

1

39:string actionName = ControllerContext.RouteData.GetRequiredString("action");

 

双击代码全选

1

40:         ActionDescriptor actionDescriptor = this.Descriptor.FindAction(ControllerContext, actionName);

 

双击代码全选

1

41:if (null == actionDescriptor)

 

双击代码全选

1

42:         {

 

双击代码全选

1

43:returnstring.Empty;

 

双击代码全选

1

44:         }

 

双击代码全选

1

45:         ExceptionPolicyAttribute exceptionPolicyAttribute = actionDescriptor.GetCustomAttributes(true).OfType<ExceptionPolicyAttribute>().FirstOrDefault()??

 

双击代码全选

1

46:            Descriptor.GetCustomAttributes(true).OfType<ExceptionPolicyAttribute>().FirstOrDefault()?? new ExceptionPolicyAttribute("");

 

双击代码全选

1

47:return exceptionPolicyAttribute.ExceptionPolicyName;

 

双击代码全选

1

48:     }

 

双击代码全选

1

49:

 

双击代码全选

1

50://获取Handle-Error-Action名称

 

双击代码全选

1

51:publicstring GetHandleErrorActionName()

 

双击代码全选

1

52:     {

 

双击代码全选

1

53:string actionName = ControllerContext.RouteData.GetRequiredString("action");

 

双击代码全选

1

54:         ActionDescriptor actionDescriptor = this.Descriptor.FindAction(ControllerContext, actionName);

 

双击代码全选

1

55:if (null == actionDescriptor)

 

双击代码全选

1

56:         {

 

双击代码全选

1

57:returnstring.Empty;

 

双击代码全选

1

58:         }

 

双击代码全选

1

59:         HandleErrorActionAttribute handleErrorActionAttribute = actionDescriptor.GetCustomAttributes(true).OfType<HandleErrorActionAttribute>().FirstOrDefault()??

 

双击代码全选

1

60:             Descriptor.GetCustomAttributes(true).OfType<HandleErrorActionAttribute>().FirstOrDefault()?? new HandleErrorActionAttribute("");

 

双击代码全选

1

61:return handleErrorActionAttribute.HandleErrorAction;

 

双击代码全选

1

62:     }

 

双击代码全选

1

63:

 

双击代码全选

1

64://用于执行Handle-Error-Action的ActionInvoker

 

双击代码全选

1

65:public HandleErrorActionInvoker HandleErrorActionInvoker { get; private set; }

 

双击代码全选

1

66:

 

双击代码全选

1

67:public ExtendedController()

 

双击代码全选

1

68:     {

 

双击代码全选

1

69:this.HandleErrorActionInvoker = new HandleErrorActionInvoker();

 

双击代码全选

1

70:     }

 

双击代码全选

1

71: }

 

ExtendedController 的Descriptor属性用于返回描述自身的ControllerDescriptor对象,实际上是一个 ReflectedControllerDescriptor对象。为了避免频繁的反射操作造成对性能的影响,我们将基于某个类型解析出来的 ReflectedControllerDescriptor对象进行了全局性缓存。
GetExceptionPolicyName方法用 于返回当前采用的异常处理策略名称。异常处理策略名称是通过具有如下定义的ExceptionPolicyAttribute特性来指定的。该特性既可以 应用在Controller类型上,也可以应用在Action方法上,换句话说,我们可以采用不同的策略来处理从不同Action执行过程中抛出的异常。 GetExceptionPolicyName利用ControllerDesctior和ActionDescriptor可以很容易地得到应用的 ExceptionPolicyAttribute特性,进而得到相应的异常处理策略名称。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

Grow your business fast with

Suku