如何使ActionFilter on action方法优先于控制器上的相同ActionFilter

时间:2009-05-29 19:29:04

标签: asp.net-mvc

由于asp.net mvc自11月以来发生了很大的变化,有没有人能够解决这个问题:

Resolve FilterAttributes On Controller And Action

Phil说控制器上的ActionFilter只是将属性应用于控制器的所有操作方法的简写,如果我在控制器和操作方法上放置相同的ActionFilter属性,它就会运行两次。但这似乎不是自然行为,因为编译器甚至不会让你多次直接在一个方法上放置相同的属性。

2 个答案:

答案 0 :(得分:7)

通过在每个过滤器上指定Order属性,过滤器可以优先于另一个过滤器。例如......

[MyFilter(Order=2)]
public class MyController : Controller
{
    [MyFilter(Order=1)]
    public ActionResult MyAction()
    {
        //...
    }
}

在此示例中,action方法上的过滤器将在控制器上的文件管理器之前执行。

HTH

答案 1 :(得分:2)

我找到了一种方法,通过排序,继承和AttributeUsage参数“作弊”来做到这一点

首先,为控制器定义ActionFilter

[AttributeUsage(AttributeTargets.Class)]
public class FilterController : ActionFilterAttribute
{
    public FilterController()
    {
        this.Order = 2;
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (!filterContext.HttpContext.Items.Contains("WeAlreadyWentThroughThis"))
        {
                // do our thing
            filterContext.HttpContext.Items.Add("WeAlreadyWentThroughThis", "yep");
            base.OnActionExecuted(filterContext);
        }
    }
}

然后继承您的action属性的类

[AttributeUsage(AttributeTargets.Method)]
public class FilterAction : FilterController
{
    public FilterAction()
    {
        this.Order = 1;
    }
}

它远非完美,因为您必须依赖HttpContext和两个类(尽管您可以使用命名空间来命名两个类相同)。但是,您可以通过编译器强制检查类或操作的属性范围,并且在键入代码时不会忘记订单参数。