当前位置:  开发笔记 > 编程语言 > 正文

在ASP.NET Web API 2中禁用*all*异常处理(为我自己腾出空间)?

如何解决《在ASP.NETWebAPI2中禁用*all*异常处理(为我自己腾出空间)?》经验,为你挑选了1个好方法。

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

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

但是,HttpErrorResponse在我可以访问之前,我想要捕获的一些异常被Web API管道捕获并转换为s.在这个过程中,我丢失了很多关于错误的细节,所以在调试时我无法得到有用的堆栈跟踪(调试器在抛出异常时甚至不会停止 - 我必须手动单步执行代码并查看它失败的地方......).

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

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());在我的启动配置,但在执行后看着它Next.Invoke(context)通过

context.Get(Constants.ContextKeys.Exception);

仍然没有给我所有我想要的细节,以及没有在调试器的故障点停止.

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

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

Web API中的内置错误处理捕获了一些(但不是全部)异常,并将它们重写为500个响应.

我想捕获所有异常,进行一些日志记录,然后使用我选择的信息发出500个响应(对于大多数异常,请参阅下一个项目符号).

还有一些异常表示业务逻辑故障,我想为此返回40x错误.

我希望它位于(app)管道的顶部,即包装请求生命周期中的所有其他内容

我想使用OWIN来处理这个问题,以便将其移植到可能的未来自托管方案中(也就是说,这个应用程序将永远托管在IIS上 - 这些应用程序将永远存在于IIS - HTTP模块中,Global.asax.cs等不相关这里).

Tomas Aschan.. 18

更新:我在博客上写了这个.在研究博客文章时,我发现了一些改进的潜力; 我已经更新了这个答案的相关部分.有关为什么我认为这比其他所有建议或默认行为更好的详细信息,请阅读整篇文章:)


我现在已经采用以下方法,即使不是100%符合我的要求,它似乎也可以正常工作:

创建一个类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;
    }
}

让该类替换IExceptionHandler Web API 的服务:

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

创建一个中间件类,它做我想要的:

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

首先在堆栈中注册该中间件:

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

我还是会给那些想出来的人奖励(赏金过期......)我仍然在寻找一个更好的解决方案,例如,当一个未处理的异常被抛出时会中断.(当我在处理程序中重新抛出异常时,这种方法会使VS中断,但原始调用堆栈丢失;我必须在错误行处设置断点并再次调试,以便在抛出异常时拦截状态.)



1> Tomas Aschan..:

更新:我在博客上写了这个.在研究博客文章时,我发现了一些改进的潜力; 我已经更新了这个答案的相关部分.有关为什么我认为这比其他所有建议或默认行为更好的详细信息,请阅读整篇文章:)


我现在已经采用以下方法,即使不是100%符合我的要求,它似乎也可以正常工作:

创建一个类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;
    }
}

让该类替换IExceptionHandler Web API 的服务:

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

创建一个中间件类,它做我想要的:

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

首先在堆栈中注册该中间件:

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

我还是会给那些想出来的人奖励(赏金过期......)我仍然在寻找一个更好的解决方案,例如,当一个未处理的异常被抛出时会中断.(当我在处理程序中重新抛出异常时,这种方法会使VS中断,但原始调用堆栈丢失;我必须在错误行处设置断点并再次调试,以便在抛出异常时拦截状态.)


哇.你有很多乐趣!太奇妙了!可能值得一篇博文!
推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有