Owin WebApi服务忽略ExceptionFilter

时间:2016-05-16 18:51:33

标签: c# asp.net-web-api owin asp.net-apicontroller

栈,

由于某些原因,我的Owin WebApi服务忽略了我们的自定义异常处理程序。我正在关注asp.net exception handling的文档。以下是简化的实现细节(清除了业务专有的东西)。

你能指出我在忽视的东西吗?

自定义例外过滤器:

public class CustomExceptionFilter : ExceptionFilterAttribute
{
   public override void OnException(HttpActionExecutedContext actionExecutedContext)
   {
       actionExecutedContext.Response.StatusCode = HttpStatusCode.NotFound;
       actionExecutedContext.Response.Content = new StringContent("...my custom business...message...here...");
   }
}

启动期间:

var filter = new CustomExceptionFilter();
config.Filters.Add(filter);
appBuilder.UseWebApi(config);

测试控制器:

[CustomExceptionFilter]
public class TestController: ApiController
{
    public void Get()
    {
        throw new Exception(); // This is a simplification. 
                               // This is really thrown in buried 
                               // under layers of implementation details
                               // used by the controller.
    }
}

1 个答案:

答案 0 :(得分:3)

您可以尝试实施Global Error Handling in ASP.NET Web API 2。 这样,您将获得Web API中间件的全局错误处理程序,但不会获得OWIN pippeline中的其他中间件,例如授权中间件。

如果您想实现全局错误处理中间件,thisthisthis链接可以为您定位。

我希望它有所帮助。

修改

关于@ t0mm13b的评论,我会根据this的第一个Khanh TO链接给出一些解释。

对于全局错误处理,您可以编写一个自定义且简单的中间件,它只是将执行流程传递给管道中但在try块内的以下中间件。

如果管道中的以下某个中间件存在未处理的异常,则会在catch块中捕获:

public class GlobalExceptionMiddleware : OwinMiddleware
{
    public GlobalExceptionMiddleware(OwinMiddleware next) : base(next)
    { }

    public override async Task Invoke(IOwinContext context)
    {
        try
        {
            await Next.Invoke(context);
        }
        catch (Exception ex)
        {
            // your handling logic
        }
    }
}

Startup.Configuration()方法中,如果要处理所有其他中间件的异常,请将中间件首先添加到管道中。

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        app.Use<GlobalExceptionMiddleware>();
        //Register other middlewares
    }
}

正如第二个{​​{3}}链接中的Tomas Lycken指出的那样,您可以使用它来处理Web API中间件中生成的异常,从而创建一个实现IExceptionHandler的类,只抛出捕获的异常,这样,全局异常处理程序中间件将捕获它:

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();
    }
}

并且不要忘记在Web API中间件配置期间替换IExceptionHandler

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