我正在使用WebApi
。我的基本控制器上有自定义ActionFilter
,全局添加了自定义ExceptionFilter
。两者都继承自System.Web.Http.Filters
命名空间中的关联FilterAttributes,而不是mvc版本。
我一直在我的一个服务中从私有方法抛出一个异常,这个方法就是resharper在Linq语句中使用它时调用方法组的东西(在本例中是select
)。
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选择之前抛出一个异常(我已经注释掉了),那么就会按预期捕获异常。
使用fiddler,我最终得到的是:
{
"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);
}
答案 0 :(得分:1)
您可以通过编写异常过滤器来自定义Web API处理异常的方式。当控制器方法抛出任何未处理的异常[...]
时,将执行异常过滤器
问题是,如果从WebAPI方法返回IEnumerable<T>
,则在序列化期间,当IEnumerable<T>
被迭代时,将发生错误。这是Select
(以及大多数其他查询运算符)的标准行为,它只调用迭代时传递给它的方法(在本例中为MakeFooFromBar
),因此在调用{时不会抛出异常{1}}但很久以后。
您可以添加Select
以使异常在您的方法中发生。