gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 03:55:42 27 4
gpt4 key购买 nike

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

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());注册,但是执行完Next.Invoke(context)通过

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

仍然 没有提供我想要的所有详细信息,并且无法在调试器的故障点停止。

有没有一种方法可以完全关闭所有内置错误处理,以便我自己的中间件可以处理它?<​​/p>

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

  • Web API 中的内置错误处理会捕获一些(但不是全部)异常并将它们重写为 500 个响应。
  • 我想捕获所有异常,做一些日志记录,然后用我选择的信息发出 500 个响应(对于其中的大部分,请参阅下一个项目符号)。
  • 还有一些异常表明业务逻辑错误,我想针对这些异常返回 40x 错误。
  • 我希望它位于(应用)管道的顶部,即包装请求生命周期中的一切
  • 我想使用 OWIN 来处理这个问题,使其可移植到 future 可能的自托管场景(即,这个应用程序将始终托管在 IIS 上并不是一成不变的 - HTTP 模块、Global.asax.cs 等与此处无关)。

最佳答案

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


我现在采用了以下方法,它似乎工作正常,即使不是 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;
    }
    }
  • 让该类替换 Web API 的IExceptionHandler 服务:

    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<ExceptionHandlerMiddleware>()
    .UseStageMarker(PipelineStage.Authenticate)
    // other middlewares omitted for brevity
    .UseStageMarker(PipelineStage.PreHandlerExecute)
    .UseWebApi(config);

我仍然会把赏金奖励给任何提出 的人(赏金已过期...)我仍在寻找更好的解决方案,例如,当 抛出未处理的异常。 (这种方法在处理程序中重新抛出异常时使 VS 中断,但原始调用堆栈丢失;我必须在故障行设置断点并再次调试才能拦截抛出异常时的状态。)

关于c# - 在 ASP.NET Web API 2 中禁用 *所有* 异常处理(为我自己腾出空间)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34201527/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com