禁用ASP.NET Web API 2中的* all *异常处理(为我自己腾出空间)? [英] Disable *all* exception handling in ASP.NET Web API 2 (to make room for my own)?

查看:88
本文介绍了禁用ASP.NET Web API 2中的* all *异常处理(为我自己腾出空间)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在中间件组件中连接异常处理,如下所示:

public override async Task Invoke(IOwinContext context)
{
    try
    {
        await Next.Invoke(context);
    }
    catch (Exception ex)
    {
        // Log error and return 500 response
    }
}

但是,我想捕获的一些异常在被Web API管道捕获并转换为HttpErrorResponse之前就可以获取.在此过程中,我丢失了许多有关错误的详细信息,因此在进行调试等操作时,我无法获得有用的堆栈跟踪信息(引发异常时调试器甚至都不会停止-我必须手动浏览代码,看看失败了...).

我尝试通过以下实现添加自定义异常处理程序:

public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
    var owinContext = context.Request.GetOwinContext();
    owinContext.Set(Constants.ContextKeys.Exception, context.Exception);
    return Task.FromResult(0);
}

在我的启动配置中通过config.Services.Replace(typeof(IExceptionHandler), new MyExceptionHandler());注册,但是在通过

context.Get<Exception>(Constants.ContextKeys.Exception);

执行后通过

context.Get<Exception>(Constants.ContextKeys.Exception);

查看

context.Get<Exception>(Constants.ContextKeys.Exception);

still 并没有提供我想要的所有详细信息,也没有提供调试器在故障点停止的信息.

有没有办法完全 关闭所有内置错误处理,以便我自己的中间件可以解决?

澄清,因为很多人似乎误会了我的追求:

  • Web API中的内置错误处理功能捕获一些(但不是全部)异常并将其重写为500个响应.
  • 我想捕获所有 异常,进行一些日志记录,然后然后用我选择的信息发出500个响应 (对于大多数情况,请参阅下一个项目符号.)
  • 还有一些表示业务逻辑故障的异常,我想为其返回40倍的错误.
  • 我希望它位于(app)管道的顶部,即在请求生命周期中包装其他其他
  • 我想使用OWIN来处理此问题,以使其可移植到将来可能出现的自托管方案(即,并非始终将这个应用程序始终托管在IIS上是一成不变的-HTTP模块,Global.asax.cs等)在这里不相关).

解决方案

更新: 解决方案

Update: I blogged about this. When researching the blog post, I found some potential for improvement; I've updated the relevant parts of this answer. For more detail on why I think this is better than all other suggestions here, or the default behavior, read the entire post :)


I have now gone with the following approach, which seems to work OK, even if not 100 % compliant with what I was looking for:

  • Create a class PassthroughExceptionHandler:

    public class PassthroughExceptionHandler : IExceptionHandler
    {
        public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
        {
            // don't just throw the exception; that will ruin the stack trace
            var info = ExceptionDispatchInfo.Capture(context.Exception);
            info.Throw();
            return Task.CompletedTask;
        }
    }
    

  • Let that class replace the IExceptionHandler service of Web API:

    config.Services.Replace(typeof(IExceptionHandler), new PassthroughExceptionHandler());
    

  • Create a middleware class which does what I want:

    public class ExceptionHandlerMiddleware
    {
        public override async Task Invoke(IOwinContext context)
        {
            try
            {
                await Next?.Invoke(context);
            }
            catch (Exception ex)
            {
                // handle and/or log
            }
        }
    }
    

  • Register that middleware first in the stack:

    app.Use<ExceptionHandlerMiddleware>()
       .UseStageMarker(PipelineStage.Authenticate)
       // other middlewares omitted for brevity
       .UseStageMarker(PipelineStage.PreHandlerExecute)
       .UseWebApi(config);
    

I will still award the bounty to anyone who comes up with (bounty expired...) I'm still looking for a better solution, which, for example, breaks when an unhandled exception is thrown. (This approach makes VS break when I rethrow the exception in the handler, but the original call stack is lost; I have to set a breakpoint at the faulting line and debug again to be able to intercept the state when an exception is thrown.)

这篇关于禁用ASP.NET Web API 2中的* all *异常处理(为我自己腾出空间)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆