GlobalFilterCollection的过滤器在ControllerInstanceFilterProvider的过滤器之前运行

问题描述:

我遇到了一个奇怪的行为,但我不确定自己是否在正确的轨道上。GlobalFilterCollection的过滤器在ControllerInstanceFilterProvider的过滤器之前运行

我有一个控制器,它会覆盖Controller基类的OnException方法。

public class ControllerFiltersController : Controller { 

    public ActionResult Index() { 

     throw new NotImplementedException(); 
    } 

    protected override void OnException(ExceptionContext filterContext) { 

     Trace.TraceInformation(
      "ControllerFiltersController Exception: " + DateTime.Now.ToString("hh:mm:ss.fff") 
     ); 
    } 
} 

我也有一个自定义的ExceptionFilter如下:

public class HandleErrorCustom : IExceptionFilter { 

    public void OnException(ExceptionContext filterContext) { 

     Trace.TraceInformation(
      "HandleErrorCustom Exception Message: " + DateTime.Now.ToString("hh:mm:ss.fff") 
     ); 
    } 
} 

然后,我把它注册为一个全球性的过滤器:

public static void RegisterGlobalFilters(GlobalFilterCollection filters) { 

    filters.Add(new HandleErrorCustom()); 
} 

我期待什么是这里的控制器实例过滤器在全局过滤器之前运行,因为由ControllerInstanceFilterProvider提供的过滤器的顺序是Int32.MinValue和t他的范围是FilterScope.First

还如这里解释:ASP.NET MVC 3 Service Location, Part 4: Filters

但结果是不同的:

iisexpress.exe信息:0:HandleErrorCustom异常消息: 06:56:49.972

iisexpress.exe信息:0:ControllerFiltersController例外: 06:56:49.974

这是一个ASP.NET MVC 4应用程序,我不知道任何会影响ASP.NET MVC 3的过滤器排序行为的更改。我在这里丢失了什么?

这是预期的行为。

过滤器排序取决于信息流动的方向。如果信息流入行动,那么订单就如您所期望的那样;如果信息流出行动,则顺序颠倒。

例如,假设您按此顺序有三个过滤器:F1,F2,F3。假设这些是动作过滤器(意思是说,他们正在侦听ActionExecuting和ActionExecuted)。该系统将运行它们的顺序如下:

F1.ActionExecuting() 
F2.ActionExecuting() 
F3.ActionExecuting() 
Action() 
F3.ActionExecuted() 
F2.ActionExecuted() 
F1.ActionExecuted() 

错误处理程序,顾名思义,即在行动返回侧运行的过滤器,所以他们的顺序是相反的。

+0

现在,我明白了。因此,具有较低值并在动作返回端运行的过滤器将首先运行。谢谢! – tugberk 2012-04-19 17:18:14