ExceptionFilterAttribute不处理属性异常

时间:2015-03-12 00:34:04

标签: asp.net-web-api action-filter actionfilterattribute

我实现了一个ExceptionFilterAttribute类,并在WebApiConfig类中注册了它。 动作过滤器运行良好并处理任何动作中发生的任何异常,但问题是:当在任何控制器属性中发生异常时,动作过滤器不处理此异常

[NotImplExceptionFilterAttribute]
public class AnyController : APIController
{
    private readonly ModelDBContext _db = new ModelDBContext();

    //some actions
}

在上述示例中,ModelDBContext的构造函数包含一些可能导致异常的逻辑。 ExceptionFilterAttribute不会处理此异常。为什么???以及如何处理它?<​​/ p>

2 个答案:

答案 0 :(得分:0)

基本上,简单的答案很简单:异常过滤器是动作级过滤器。

首先检查此图表:http://blogs.msdn.com/b/kiranchalla/archive/2012/05/06/asp-net-mvc4-web-api-stack-diagram-currently-in-development.aspx 然后导航到ApiController,第232行。在那里你可以看到,如果至少有一个过滤器,那么ExceptionFilterResult将用于包装结束动作结果。 在ExceptionFilterResult内部有简单的try-catch,如果抛出异常,则调用所有已注册的异常过滤器。 所以,上面写的所有内容的简短摘要: 1)异常过滤器不负责处理控制器动作之上的错误 2)当DI容器创建控制器实例并且ModelDBContext抛出异常时,异常过滤器不存在

我希望这能回答你的问题。

答案 1 :(得分:0)

问题在于范围。

当控制器被实例化时,私有类成员 _db将在任何类方法执行之前初始化。这是一种CLR行为。

因此,操作过滤器不会捕获在构造/初始化控制器对象期间发生的异常,例如无法构造ModelDBContext实例。

一种解决方案是在每个请求上创建和处理ModelDBContext个实例,如果您打算优雅地处理(或记录)连接失败,有些人可能认为这是正确的方法(无论它是否适用于数据库或后端服务。)

您可能还会找到IServiceLocator以及诸如“Unity&#39;”等框架。或者&#39; Ninject&#39;有用的,这样你就不会&#34;硬编码&#34; new ModelDBContext();声明随处可见,但这是另一个主题。根本原因是您在操作方法范围之外进行初始化,操作过滤器无法捕获它。