Reputation: 24368
Since asp.net mvc has changed a lot since November, does anyone have a solution to this question:
Resolve FilterAttributes On Controller And Action
Phil said an ActionFilter on a controller is just shorthand for applying the attribute to all action methods of the controller, and it is true, if I put the same ActionFilter attribute on the controller and on an action method, it will run twice. But this doesn't seem like natural behavior since the compiler won't even let you put the same attribute directly on a method multiple times.
Upvotes: 7
Views: 3513
Reputation: 14962
I found one way to do it by "cheating" a bit with the ordering, inheritance and the AttributeUsage parameter
First, define your ActionFilter for the controller
[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);
}
}
}
Then inherit the class for your action attribute
[AttributeUsage(AttributeTargets.Method)]
public class FilterAction : FilterController
{
public FilterAction()
{
this.Order = 1;
}
}
It's far from perfect since you have to rely on HttpContext and two classes (though you could use namespaces to name both classes the same). But you get compiler-enforced check of the attribute scope for class or action and you won't forget an order parameter when typing the code.
Upvotes: 3
Reputation: 778
A filter can take precedence over another filter by specifing the Order property on each filter. For example...
[MyFilter(Order=2)]
public class MyController : Controller
{
[MyFilter(Order=1)]
public ActionResult MyAction()
{
//...
}
}
In this example the filter on the action method would execute before the filer on the controller.
HTH
Upvotes: 11