ASP.NET MVC集成EntLib实现“自动化”异常处理[实现篇]
通过《实例篇》的实演示可以看出我们通过扩展实现的自动异常处理机制能够利用EntLib的EHAB根据执行的一场处理策略对某个Action方法执行过程中抛出的异常进行处理。对于处理后的结果,则按照如下的机制对请求进行响应。[源代码从这里下载][本文已经同步到《How ASP.NET MVC Works?》中]
一、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-web-api – Asp.Net核心WebAPI CORS无效
- asp.net – 将http状态代码设置为XXX.X?
- MVC3 .NET会话随机丢失会话值并返回null
- asp.net – 我可以使用构造函数动态创建用户控件
- asp.net – 如何将其他页面包含到aspx文件中
- asp.net-mvc – RavenDB部署问题
- ASP.NET MVC中使用区域时的配置错误4
- asp.net-mvc – 处理ASP.NET MVC中的路由错误
- asp.net – 使用EditorFor和Twitter Bootstrap来
- asp.net-mvc – 定义脚手架. (关于动态数据和ASP