通过《实例篇》的实演示可以看出我们通过扩展实现的自动异常处理机制能够利用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
所有的这些都是通过一个自定义的ExceptionFilter来实现的。不过我们并没有定义任何的ExceptionFilter特性,而是将异常处理实现在一个自定义的ExtendedController基类中,对异常的自动处理实现在重写的OnException方法中,不过在介绍该方法的逻辑之前我们先来看看定义在ExtendedController中的其他辅助成员。
class ExtendedController: Controller
2: {
new Dictionary<Type, ControllerDescriptor>();
object();
5:
void OnException(ExceptionContext filterContext)
7: {
//省略成员
9: }
10:
//描述当前Controller的ControllerDescriptor
public ControllerDescriptor Descriptor
13: {
14: get
15: {
16: ControllerDescriptor descriptor;
out descriptor))
18: {
return descriptor;
20: }
lock (syncHelper)
22: {
out descriptor))
24: {
return descriptor;
26: }
else
28: {
this.GetType());
this.GetType(), descriptor);
return descriptor;
32: }
33: }
34: }
35: }
//获取异常处理策略名称
string GetExceptionPolicyName()
38: {
);
this.Descriptor.FindAction(ControllerContext, actionName);
null == actionDescriptor)
42: {
string.Empty;
44: }
true).OfType<ExceptionPolicyAttribute>().FirstOrDefault()??
);
return exceptionPolicyAttribute.ExceptionPolicyName;
48: }
49:
//获取Handle-Error-Action名称
string GetHandleErrorActionName()
52: {
);
this.Descriptor.FindAction(ControllerContext, actionName);
null == actionDescriptor)
56: {
string.Empty;
58: }
true).OfType<HandleErrorActionAttribute>().FirstOrDefault()??
);
return handleErrorActionAttribute.HandleErrorAction;
62: }
63:
//用于执行Handle-Error-Action的ActionInvoker
private set; }
66:
public ExtendedController()
68: {
new HandleErrorActionInvoker();
70: }
71: }