Passing in variables to custom Action Filters

20 Aug 2013 .Net, C#, Filters, MVC No Comments

Sometimes it is useful to have a reusable custom action filter, for example for checking user authorisation to access part of the application. I would prefer not to have a separate filter for each type of user, e.g. MustBeAdminAttribute, MustBeManagerAttribute, etc. There are several ways to pass variables to a custom action filter and I will start with what I think is the best method for this particular expample.

Variables defined in the filter

The variable is defined in the filter and assigned in the controller. This can be done for multiple variables.

Controller code

[MustHaveRole(Role="admin")]
public ActionResult AdminSection()
{
    return View();
}

Action Filter

public class MustHaveRoleAttribute : ActionFilterAttribute
{
    public string Role { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!string.IsNullOrEmpty(Role))
        {
            // Use Role string to check if the current user has that role
        }
    }		
}

Access a variable defined in the Action (ActionExecutingContext)

Variables defined in the action can be accessed via the ActionExecutingContext

Controller code

[MustHaveRole]
public ActionResult AdminSection()
{
    string role = "admin";
    return View();
}

Action Filter

public class MustHaveRoleAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string role = filterContext.ActionParameters.SingleOrDefault(p => p.Key == "role").Value.ToString();
        if (!string.IsNullOrEmpty(role)) 
        { 
            // Use role string to check if the current user has that role 
        }
    }
}

Access a variable passed to the Action (ActionExecutingContext)

This is done in the same way as accessing a variable defined in the action.

Controller code

[MustHaveRole]
public ActionResult AdminSection(string role)
{
    return View();
}

Action Filter

public class MustHaveRoleAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string role = filterContext.ActionParameters.SingleOrDefault(p => p.Key == "role").Value.ToString();
        if (!string.IsNullOrEmpty(role)) 
        { 
            // Use role string to check if the current user has that role 
        }
    }
}

Access Controller Properties and Variables (ActionExecutingContext)

You can also access controller properties and values using the ActionExecutingContext

Controller code

[MustHaveRole]
public ActionResult AdminSection()
{
    ViewBag.Role = "admin";
    return View();
}

Action Filter

public class MustHaveRoleAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string role = filterContext.Controller.ViewBag["Role"].ToString();
        if (!string.IsNullOrEmpty(role)) 
        { 
            // Use role string to check if the current user has that role 
        }
        // Further examples
        string actionName = (string)filterContext.RouteData.Values["action"];
        string controllerName = (string)filterContext.RouteData.Values["controller"];
    }
}