asp.net-web-api – 哪个优先级,ASP.NET Web Api 2.0中的ExceptionFilter或ExceptionHandler?

前端之家收集整理的这篇文章主要介绍了asp.net-web-api – 哪个优先级,ASP.NET Web Api 2.0中的ExceptionFilter或ExceptionHandler?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我的web api 2.0中有一个全局ExceptionHandler,它处理所有未处理的异常,以便向api调用者返回一个友好的错误消息.
我也有一个全局ExceptionFilter,它处理一个非常特殊的异常在我的web api并返回一个具体的响应. ExceptionFilter由插件动态地添加到我的web api中,所以我不能在我的ExceptionHandler中执行它.

我想知道我是否在全球注册了ExceptionHandler和ExceptionFilter,哪一个将优先执行,首先执行?现在我可以看到ExceptionFilter正在执行ExceptionHandler之前.我也可以看到,在我的ExceptionFilter中,如果我创建一个响应,ExceptionHandler没有被执行.

假设这样做是安全的:

> ExceptionFilter在ExceptionHandler之前执行.
>如果ExceptionFilter创建一个响应,则ExceptionHandler将不被执行.

解决方法

我不得不通过System.Web.Http进行调试,以便找到我的问题的答案.所以答案是:

>可以安全地假设ExceptionFilters将在ExceptionHandler之前执行
>如果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,然后如果executionContext.Response == null,则执行ExceptionHandler.

我希望这是有用的!

猜你在找的asp.Net相关文章