我的Web api 2.0中有一个全局ExceptionHandler,它可以处理所有未处理的异常,以便向api调用者返回友好的错误消息。
我也有一个全局的ExceptionFilter,该异常处理我的Web api中一个非常特定的异常并返回一个特定的响应。 ExceptionFilter是由插件动态添加到我的Web api中的,因此我无法在ExceptionHandler中执行它的操作。

我想知道我是否同时在全局注册了ExceptionHandler和ExceptionFilter,哪个优先级高并先执行?现在,我可以看到ExceptionFilter在ExceptionHandler之前执行。而且我还可以在ExceptionFilter中看到,如果创建响应,则不会执行ExceptionHandler。

可以安全地假设:


ExceptionFilters在ExceptionHandlers之前执行。
如果ExceptionFilter创建响应,则将不执行ExceptionHandler。

最佳答案

我必须通过System.Web.Http进行调试才能找到问题的答案。因此答案是:


可以肯定地假设ExceptionFilters将在ExceptionHandlers之前执行
如果ExceptionFilter创建一个响应,则不会执行ExceptionHandler。


为什么会这样:

当您注册了ExceptionFilter以便全局执行或执行控制器操作时,所有api控制器都将从其继承的ApiController基类将结果包装在ExceptionFilterResult中,并调用其ExecuteAsync方法。这是ApiController中的代码,它执行以下操作:



if (exceptionFilters.Length > 0)
{
    IExceptionLogger exceptionLogger = ExceptionServices.GetLogger(controllerServices);
    IExceptionHandler exceptionHandler = ExceptionServices.GetHandler(controllerServices);
    result = new ExceptionFilterResult(ActionContext, exceptionFilters, exceptionLogger, exceptionHandler,
        result);
}

return result.ExecuteAsync(cancellationToken);


查看ExceptionFilterResult.ExecuteAsync方法:

try
{
    return await _innerResult.ExecuteAsync(cancellationToken);
}
catch (Exception e)
{
    exceptionInfo = ExceptionDispatchInfo.Capture(e);
}

// This code path only runs if the task is faulted with an exception
Exception exception = exceptionInfo.SourceException;
Debug.Assert(exception != null);

bool isCancellationException = exception is OperationCanceledException;

ExceptionContext exceptionContext = new ExceptionContext(
    exception,
    ExceptionCatchBlocks.IExceptionFilter,
    _context);

if (!isCancellationException)
{
    // We don't log cancellation exceptions because it doesn't represent an error.
    await _exceptionLogger.LogAsync(exceptionContext, cancellationToken);
}

HttpActionExecutedContext executedContext = new HttpActionExecutedContext(_context, exception);

// Note: exception filters need to be scheduled in the reverse order so that
// the more specific filter (e.g. Action) executes before the less specific ones (e.g. Global)
for (int i = _filters.Length - 1; i >= 0; i--)
{
    IExceptionFilter exceptionFilter = _filters[i];
    await exceptionFilter.ExecuteExceptionFilterAsync(executedContext, cancellationToken);
}

if (executedContext.Response == null && !isCancellationException)
{
    // We don't log cancellation exceptions because it doesn't represent an error.
    executedContext.Response = await _exceptionHandler.HandleAsync(exceptionContext, cancellationToken);
}


您可以看到先执行了ExceptionLogger,然后执行了所有ExceptionFilter,然后如果执行了executeContext.Response == null,则将执行ExceptionHandler。

我希望这是有用的!

关于asp.net-web-api - 在ASP.NET Web Api 2.0中,哪一个具有优先权,是ExceptionFilter还是ExceptionHandler?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28127042/

10-10 07:39