asp.net-web-api – 哪个优先级,ASP.NET Web Api 2.0中的Excepti
我的web api 2.0中有一个全局ExceptionHandler,它处理所有未处理的异常,以便向api调用者返回一个友好的错误消息.
我也有一个全局ExceptionFilter,它处理一个非常特殊的异常在我的web api并返回一个具体的响应. ExceptionFilter由插件动态地添加到我的web api中,所以我不能在我的ExceptionHandler中执行它. 我想知道我是否在全球注册了ExceptionHandler和ExceptionFilter,哪一个将优先执行,首先执行?现在我可以看到ExceptionFilter正在执行ExceptionHandler之前.我也可以看到,在我的ExceptionFilter中,如果我创建一个响应,ExceptionHandler没有被执行. 假设这样做是安全的: > ExceptionFilter在ExceptionHandler之前执行. 解决方法
我不得不通过System.Web.Http进行调试,以便找到我的问题的答案.所以答案是:
>可以安全地假设ExceptionFilters将在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. 我希望这是有用的! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |