我刚刚注意到MVC3中ActionFilterAttribute优先级的一个奇怪行为。事实证明,如果Controller和Action都使用具有AllowMultiple = false(默认值)的相同ActionFilterAttribute进行修饰,则会选择具有HIGHER Order值的Controller。在平局的情况下(即两个Order值相同),则选择Action上的过滤器。我一直认为Action的过滤器总是被选中(如果有的话),无论Order值如何。例子:
选择过滤操作:
[MyActionFilter(Name = "Controller")] // same as Order = -1
public class HomeController : Controller {
[MyActionFilter(Name = "Action")] // same as Order = -1
public ActionResult Index() {
return Content("Hello");
}
}
选择了控制器上的过滤器:
[MyActionFilter(Name = "Controller", Order = 1)]
public class HomeController : Controller {
[MyActionFilter(Name = "Action")] // same as Order = -1
public ActionResult Index() {
return Content("Hello");
}
}
选择过滤操作:
[MyActionFilter(Name = "Controller", Order = 1)]
public class HomeController : Controller {
[MyActionFilter(Name = "Action", Order = 1)]
public ActionResult Index() {
return Content("Hello");
}
}
选择了控制器上的过滤器:
[MyActionFilter(Name = "Controller", Order = 20)]
public class HomeController : Controller {
[MyActionFilter(Name = "Action", Order = 1)]
public ActionResult Index() {
return Content("Hello");
}
}
这是一个错误还是设计?我从版本1开始就一直使用MVC,从未注意到这个过滤器选择优先级。它总是这样吗?
由于
答案 0 :(得分:3)
如果设置AllowMultiple = false
并且在控制器和操作上都有相同的操作过滤器,则控制器上的操作过滤器从不执行。如果设置AllowMultiple=true
,则控制器上的过滤器首先执行相同的顺序。
ASP.NET MVC 3中发生的变化如下:
在以前的ASP.NET MVC版本中, 每个请求都会创建操作过滤器 除了少数情况。这种行为 从来都不是保证行为但是 仅仅是一个实现细节和 过滤器的合同是 认为他们是无国籍的。在ASP.NET中 MVC 3,过滤器缓存更多 积极。因此,任何习惯 不正确存储的动作过滤器 实例状态可能会被破坏。
所以要确保你正确地测试了这个:
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
public class MyActionFilterAttribute : ActionFilterAttribute
{
public string Name { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Put a breakpoint here and inspect the value of the Name property ====>
var name = Name;
base.OnActionExecuting(filterContext);
}
}