1

我应该如何在无状态 Web API 中处理我的控制器方法的全局异常处理?我的目标是避免在我的控制器中出现冗长的 try/catch 语句。

我能够使用 IIS 托管的 Web API 使用我在我的WebAPIConfig.cs. 这在 OWIN 托管的 API(如在 Service Fabric 中)中不会立即生效。因此,在 SF 无状态 Web API 中,我创建了一个 Owin 中间件并在其中注册了该中间件,Startup.cs但它不起作用。在我的中间件代码的响应管道中忽略了 catch 块。

...

public override async Task Invoke(IOwinContext context)
{
    try
    {
        //It goes here
        await Next.Invoke(context);
    }
    catch (Exception ex)
    {
        //This catch block does not get called????
        HandleException(ex, context);
    }
}
4

1 回答 1

0

在大量挖掘解决方案之后,由于已经有很多类似的问题,我对 Web API 和 OWIN 管道有了更好的理解。SO中的这个问题为我提供了很多信息:在ASP.NET Web API 2中禁用*所有*异常处理(为我自己腾出空间)?

首先,默认情况下会处理 Web API 异常,这意味着异常已被处理,因此它不会向上传播堆栈跟踪。这就是为什么上面的 catch 块(来自我发布的问题)没有被调用的原因。为了让它被调用,我需要通过这个替换IExceptionWeb API(in startup.cs) 的处理程序:

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

这个自定义处理程序所做的只是将异常向下转发到堆栈并让 OWIN 全局异常中间件完成工作。

PassthroughExceptionHandler 是这样实现的:

public class PassthroughExceptionHandler : IExceptionHandler
{
    public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
    {
        var info = ExceptionDispatchInfo.Capture(context.Exception);
        info.Throw();
    }
}

请注意,这使用ExceptionDispatchInfo. 还有其他解决方案有不同的实现,但到目前为止,这个解决方案为我提供了我需要的东西,即最终将异常包装到我的常见错误响应模型中OwinGlobalExceptionHandler

于 2017-01-06T14:11:59.380 回答