异常处理 – 如何处理WebAPI中的控制器构造函数中的异常?
说我有一个构造函数,它的初始化可能会由于我无法控制的原因而抛出异常.
FantasticApiController(IAwesomeGenerator awesome,IBusinessRepository repository,IIceCreamFactory factory) { Awesome = awesome; Repository = repository; IceCream = factory.MakeIceCream(); DoSomeInitialization(); // this can throw an exception } 通常,当WebAPI中的Controller操作抛出异常时,我可以通过一个csutom ExceptionFilterAttribute来处理它: public class CustomErrorHandler { public override void OnException(HttpActionExecutedContext context) { // Critical error,this is real bad. if (context.Exception is BubonicPlagueException) { Log.Error(context.Exception,"CLOSE EVERYTHING!"); Madagascar.ShutdownAllPorts(); } // No big deal,just show something user friendly throw new HttpResponseException(new HttpResponseMessage { Content = new StringContent("Hey something bad happened. " + "Not closing the ports though"),StatusCode = HttpStatusCode.InternalServerError; }); } 所以如果我有一个BoardPlane API方法抛出一个BubonicPlagueException,那么我的CustomerErrorHandler将关闭端口到马达加斯加,并按预期的方式将其记录为一个错误.在其他情况下,当它不是很严重时,我只显示一些用户友好的消息并返回500 InternalServerError. 但是在DoSomeInitialization引发异常的情况下,这绝对没有.如何处理WebAPI控制器构造函数中的异常? 解决方法
创建WebApi控制器,因此通过HttpControllerActivators调用构造函数.默认的激活器是System.Web.Http.Dispatcher.DefaultHttpControllerActivator.
选项1& 2在github这里https://github.com/markyjones/StackOverflow/tree/master/ControllerExceptionHandling/src 方案1的工作相当不错,涉及使用DI容器(您可能已经使用了一个).我使用Ninject作为我的例子,并使用“Interceptor”Read More拦截并尝试/捕获对DefaultHttpControllerActivator的Create方法的调用.我至少知道AutoFac和Ninject可以做一些类似于以下的事情: 创建拦截器 我不知道你的马达加斯加和日志项目的生命周期是什么,但是他们可以很好地注入到你的拦截器中 public class ControllerCreationInterceptor : Ninject.Extensions.Interception.IInterceptor { private ILog _log; private IMadagascar _madagascar; public ControllerCreationInterceptor(ILog log,IMadagascar madagascar) { _log = log; _madagascar = madagascar; } 但是,请记住在你的问题中,Log和Madagascar是一种静态全局的例子 public class ControllerCreationInterceptor : Ninject.Extensions.Interception.IInterceptor { public void Intercept(Ninject.Extensions.Interception.IInvocation invocation) { try { invocation.Proceed(); } catch(InvalidOperationException e) { if (e.InnerException is BubonicPlagueException) { Log.Error(e.InnerException,"CLOSE EVERYTHING!"); Madagascar.ShutdownAllPorts(); //DO SOMETHING WITH THE ORIGIONAL ERROR! } //DO SOMETHING WITH THE ORIGIONAL ERROR! } } } 最终注册拦截器在全局asax或App_Start(NinjectWebCommon) kernel.Bind<System.Web.Http.Dispatcher.IHttpControllerActivator>() .To<System.Web.Http.Dispatcher.DefaultHttpControllerActivator>().Intercept().With<ControllerCreationInterceptor>(); 选项2是实现自己的Controller Activator实现IHttpControllerActivator接口,并在Create方法中处理创建Controller的错误.您可以使用装饰器图案来包装DefaultHttpControllerActivator: public class YourCustomControllerActivator : IHttpControllerActivator { private readonly IHttpControllerActivator _default = new DefaultHttpControllerActivator(); public YourCustomControllerActivator() { } public System.Web.Http.Controllers.IHttpController Create(System.Net.Http.HttpRequestMessage request,System.Web.Http.Controllers.HttpControllerDescriptor controllerDescriptor,Type controllerType) { try { return _default.Create(request,controllerDescriptor,controllerType); } catch (InvalidOperationException e) { if (e.InnerException is BubonicPlagueException) { Log.Error(e.InnerException,"CLOSE EVERYTHING!"); Madagascar.ShutdownAllPorts(); //DO SOMETHING WITH THE ORIGIONAL ERROR! } //DO SOMETHING WITH THE ORIGIONAL ERROR! return null; } } } 一旦你有自己的定制激活器,默认的激活器可以是全局asax中的switched out: GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator),new YourCustomControllerActivator()); 选项3当然,如果您在构造函数中的初始化不需要访问实际的Controllers方法,属性等,即假设可以从构造函数中删除…那么将初始化变为一个过滤器 public class MadagascarFilter : AbstractActionFilter { public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) { try{ DoSomeInitialization(); // this can throw an exception } catch(BubonicPlagueException e){ Log.Error(e,"CLOSE EVERYTHING!"); Madagascar.ShutdownAllPorts(); //DO SOMETHING WITH THE ERROR } base.OnActionExecuting(actionContext); } public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext) { base.OnActionExecuted(actionExecutedContext); } public override bool AllowMultiple { get { return false; } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – 多个用户控件和JavaScript
- ASP.NET中的<%%>(嵌入式代码块)
- asp.net-mvc – 如果使用LINQ to SQL,还有什么理由学习SQL查
- ASP.NET C#5异步Web应用程序使用异步和等待
- asp.net-mvc – 是否有官方的ASP.NET MVC参考/示例应用程序
- ASP.NET WebService Response.Write乱码解决
- ASP.NET MVC4 WebApi路由中包含文件名
- 如何在Substitution控件中使用ASP.Net服务器控件?
- asp.net – 绕过Windows身份验证
- asp.net – .Net System.Mail.Message添加多个“To”地址
- ASP.NET FileUpload Control – 缓冲到磁盘时的安
- 用于asp.net应用程序的脚本引擎
- asp.net-core – 丰富Serlilogs,每个hangfire工作
- asp.net-mvc – ASP.NET MVC – 能够处理数组的自
- 跨项目分发ASP.NET用户控件的技术
- unit-testing – 对ActionFilter进行单元测试 –
- 三种属性操作性能比较:PropertyInfo + Expressi
- Asp.net C的PDF或其他“报告查看器”选项#
- Asp.Net / C#何时?等于A? (é等于E)
- asp.net页面SqlCacheDependency缓存实例