ExceptionFilter разница между OnExceptionAsync vs .OnException

Что это.

При написании фильтра исключений custome в MVC или WebApi, в чем разница между методами OnExceptionAsync и OnException? Это так, что OnExceptionAsync вызывается только при использовании асинхронных контроллеров? Или оба вызываются?

Когда использовать какой?

Как использовать OnExceptionAsync, который возвращает результат задачи?

Некоторые базовые коды для иллюстрации:

public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        //TODO exception handling
    }

    public override Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
    {
        //TODO exception handling
    }
}

Ответ 1

Я думаю, что OnExceptionAsync используется с асинхронными действиями.

Если вам нужен простой сценарий, такой как отправка сериализуемого описания ошибки, вы можете переопределить OnException, а не OnExceptionAsync, так как OnExceptionAsync вызывает OnException в реализации ExceptionFilterAttribute по умолчанию:

public override void OnException(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
{
    actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.InternalServerError, new 
    {
        Message = "An unexpected error has occured",
        Description = actionExecutedContext.Exception.Message
    });

    actionExecutedContext.Response.Headers.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue()
    {
        NoCache = true,
        NoStore = true
    };
}

Но вы можете записать исключение в базу данных и воспользоваться асинхронным поведением:

public override async Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
{
    await LogException(actionExecutedContext.Exception);
}

Ключевые слова async и await помогут вам управлять асинхронным поведением. Вам не нужно возвращать объект Task.