2

我正在使用WebApi. ActionFilter我的基本控制器上有一个自定义,并在ExceptionFilter全球范围内添加了一个自定义。两者都继承自命名空间中关联的 FilterAttributes System.Web.Http.Filters,而不是 mvc 版本。

我的一个服务中的私有方法抛出了一个异常,当它在 Linq 语句(在本例中为 a select)中使用时,这个方法就是 resharper 调用的方法组。

public IEnumerable<Foo> GetFoos()
{
    IEnumerable<Bar> bars = _work.BarRepository.GetAll();

    //throw new Exception("I'm visible to the filters");

    IEnumerable<Foo> foos = bars.Select(MakeFooFromBar);

    return foos;
}

private Foo MakeFooFromBar(Bar bar)
{
    // an exception is being thrown here
    // which is not being caught by the filers
    throw new Exception("I am invisible to the filters");
}

任一过滤器都未捕获此异常(请参阅下面的过滤器)。我的操作过滤器说没有异常,我的异常过滤器永远不会被击中。如果我在 Linq 选择(我已注释掉的那个)之前抛出异常,那么异常会按预期捕获。

使用提琴手,我最终得到的是:

{  
   "message":"An error has occurred.",
   "exceptionMessage":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.",
   "exceptionType":"System.InvalidOperationException",
   "stackTrace":null,
   "innerException":{  
      "message":"An error has occurred.",
      "exceptionMessage":"I am invisible to the filters",
      "exceptionType":"System.Exception",
      "stackTrace":""
   }
}

我的动作过滤器的一部分:

public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
    Exception exception = actionExecutedContext.Exception;

    if (exception == null)
    {
        // do things
    }
    else
    {
        // do some other things
    }
}

和我的异常过滤器的一部分:

public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
    // return early on certain kinds of exceptions...

    _loggedErrorService.Log(actionExecutedContext.Exception);
}
4

1 回答 1

2

文档

您可以通过编写异常过滤器来自定义 Web API 如何处理异常。当控制器方法抛出任何未处理的异常时执行异常过滤器[...]

问题是,如果您IEnumerable<T>从 WebAPI 方法返回 an ,则在序列化过程中会发生错误,此时IEnumerable<T>迭代 。这是Select(以及大多数其他查询运算符)的标准行为,它只调用在迭代时传递给它的方法(MakeFooFromBar在这种情况下),因此在您调用时不会抛出异常,Select而是在很久以后才抛出异常。

您可以添加一个.ToList以使异常在您的方法中发生。

于 2018-02-16T14:31:09.973 回答