异常过滤器之外的异常处理?

时间:2012-07-13 15:59:48

标签: asp.net asp.net-web-api

使用Asp.net WebApi(RC),如何捕获global.asax中Exception FiltersApplication_Error()未捕获的错误?

有了这两个原因,似乎仍然没有涵盖一类例外。例如:ApiControllerActionSelector_AmbiguousMatch错误(Multiple actions were found that match the request: {0})。

我没有特别关注上述错误,这个错误只是指出我的异常过滤器或Application_Error没有捕获到一类错误方法。

那我怎样才能涵盖所有基地?

2 个答案:

答案 0 :(得分:3)

你是对的,有几类异常没有被Application_Error或ExceptionFilter捕获。 Web API请求管道与ASP.NET MVC管道分开处理(至少通过MVC 4),因此MVC Application_Error不会启动。此外,如果您的应用程序抛出HttpResponseException类型例外,那么{strong}将不会被ExceptionFilter by design捕获(请参阅ExceptionFilter段落)。要访问 代码引发的所有异常,您需要按照以下代码行创建DelegatingHandler

public class ResponseExceptionTrapper : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        return base
            .SendAsync(request, cancellationToken)
            .ContinueWith(response =>
                 {
                     var result = response.Result;
                     if (!result.IsSuccessStatusCode)
                     {
                          var exceptionResult = string.Format(
                               "Response exception: Path({0}) Status({1}) ",
                               request.RequestUri,
                               result.StatusCode);

                          if (result.Content != null)
                          {
                               var exceptionReadTask =
                                      result.Content.ReadAsStringAsync();

                               exceptionReadTask.Wait();
                               exceptionResult += "Message:\n\r" +
                                                 exceptionReadTask.Result;
                           }

                           // Do something appropriate with exceptionResult
                      }

                      return result;
                 }, cancellationToken);
    }
}

您可以在全局配置逻辑中使用此行连接处理程序:

GlobalConfiguration.Configuration.MessageHandlers.Add(
     new ResponseExceptionTrapper());

答案 1 :(得分:2)

我相信只有在调用动作时才会调用异常过滤器(在这种情况下,会有一个try / catch)。在管道中之前会弹出不明确的匹配错误,之后可能会出现其他错误(例如格式化程序错误)。

我不确定您是否可以使用一个解决方案来解决所有方面(因为托管实施可能会有所不同),但您可以尝试覆盖HttpControllerDispatcher。此类是管道中使用的“根”类之一。具体来说,您可以覆盖SendAsync来执行try / catch并相应地处理。