Служба Owin WebApi игнорирует ExceptionFilter

Куча,

По какой-то причине мой сервис Owin WebApi игнорирует наш собственный обработчик исключений. Я следую документации по обработке исключений asp.net . Вот упрощенные детали реализации (удалены проприетарные вещи).

Можете ли вы указать, что я пропускаю?

Пользовательский фильтр исключений:

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.
    }
}

person bartonm    schedule 16.05.2016    source источник
comment
У меня есть проект, который делает именно этот шаблон, за исключением OnException для изменения ответа I throw new HttpResponseException(new HttpResponseMessage(... вместо изменения actionExecutedContext.   -  person Steve Wakeford    schedule 20.05.2016


Ответы (1)


Вы можете попробовать реализовать глобальную обработку ошибок в веб-API ASP.NET 2. Таким образом вы получите глобальный обработчик ошибок для ПО промежуточного слоя веб-API, но не для других ПО промежуточного слоя в конвейере OWIN, например, для авторизации.

Если вы хотите реализовать промежуточное ПО для обработки глобальных ошибок, это, эта и эта ссылки могут вам помочь.

Я надеюсь, что это помогает.

ИЗМЕНИТЬ

Что касается комментария @ t0mm13b, я дам небольшое объяснение, основанное на первой ссылке этой от 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
    }
}

Как указал Томас Ликен во втором эту ссылку, вы можете использовать ее для обработки исключений, сгенерированных промежуточным программным обеспечением веб-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();
    }
}

И не забудьте заменить IExceptionHandler во время настройки промежуточного программного обеспечения веб-API:

config.Services.Replace(typeof(IExceptionHandler), new PassthroughExceptionHandler());
person jumuro    schedule 20.05.2016