代码之家  ›  专栏  ›  技术社区  ›  JeremyWeir

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

  •  4
  • JeremyWeir  · 技术社区  · 16 年前

    自从11月以来,ASP.NET MVC发生了很大的变化,是否有人能解决这个问题:

    Resolve FilterAttributes On Controller And Action

    菲尔说,控制器上的actionfilter只是将该属性应用于控制器的所有操作方法的简写,如果我将相同的actionfilter属性应用于控制器和操作方法,它将运行两次。但这看起来不像是自然行为,因为编译器甚至不允许您多次将同一个属性直接放在一个方法上。

    2 回复  |  直到 14 年前
        1
  •  7
  •   robertz    16 年前

    通过在每个筛选器上指定order属性,筛选器可以优先于另一个筛选器。例如。。。

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

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

    高温高压

        2
  •  2
  •   samy    14 年前

    我发现了一种方法,就是在排序、继承和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);
            }
        }
    }
    

    然后继承动作属性的类

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

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