ASP.NET MVC: Ignore custom attribute in a base controller class

asp.net-mvc, base-class, custom-attributes, inheritance

Solution

I had a similar need for something like this and found that by creating an authorization filter (implementing/deriving from `FilterAttribute, IAuthorizationFilter`) rather than a regular action filter (deriving from `ActionFilterAttribute`), and setting `Inherited=true` and `AllowMultiple=false` on the attribute, that it would only run once at the appropriate spot.

This means I am able to "cascade" my filter down from a base controller (the site-wide default), to a derived controller (for example the AdminController or whatever), or even further down to an individual action method.

For example,

[AttributeUsage(AttributeTargets.Class|AttributeTargets.Method, Inherited=true, AllowMultiple=false)]
public class MyCustomAttribute : FilterAttribute, IAuthorizationFilter
{
    private MyCustomMode _Mode;
    public MyCustomAttribute(MyCustomMode mode)
    {
        _Mode = mode;
    }
    public virtual void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }
        // run my own logic here.
        // set the filterContext.Result to anything non-null (such as
        // a RedirectResult?) to skip the action method's execution.
        //
        //
    }
}

public enum MyCustomMode
{
    Enforce,
    Ignore
}

And then to use it, I can apply it to my super-controller,

[MyCustomAttribute(Ignore)]
public class BaseController : Controller
{
}

And I can change/override it for specific controllers, or even for specific actions!

[MyCustomAttribute(Enforce)]
public class AdministrationController : BaseController
{
    public ActionResult Index()
    {
    }

    [MyCustomAttribute(Ignore)] 
    public ActionResult SomeBasicPageSuchAsAHelpDocument()
    {
    }
}

This allowed me to "turn off" the filter for specific cases, while still being able to apply it as a default on either the whole controller or whole application.

Good luck!

Problem

I have a number of Controllers in my project that all inherit from a controller I've named BaseController. I wrote a custom attribute that I applied to the entire BaseController class, so that each time an action runs in any of my controllers, that attribute will run first. The problem is that I have a couple of controller actions that I'd like to ignore that attribute, but I don't know how to do it. Can anyone help? I'm using MVC 1. Thanks.

Original source

Related problems