Order of Execution with Multiple Filters in Web API

Order of execution with multiple filters in web api

Some things to note here:

  1. Filters get executed in the following order for an action: Globally
    Defined Filters -> Controller-specific Filters -> Action-specific Filters.
  2. Authorization Filters -> Action Filters -> Exception
    Filters
  3. Now the problem that you seem to mention is related to
    having multiple filters of the same kind (ex: Multiple
    ActionFilterAttribute decorated on a
    controller or an action. This is the case which would not guarantee
    the order as its based on reflection.). For this case, there is a way
    to do it in Web API using custom implementation of
    System.Web.Http.Filters.IFilterProvider. I have tried the following
    and did some testing to verify it. It seems to work fine.
    You can give it a try and see if it works as you expected.

    // Start clean by replacing with filter provider for global configuration.
    // For these globally added filters we need not do any ordering as filters are
    // executed in the order they are added to the filter collection
    config.Services.Replace(typeof(IFilterProvider), new System.Web.Http.Filters.ConfigurationFilterProvider());

    // Custom action filter provider which does ordering
    config.Services.Add(typeof(IFilterProvider), new OrderedFilterProvider());

    public class OrderedFilterProvider : IFilterProvider
    {
    public IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor)
    {
    // controller-specific
    IEnumerable<FilterInfo> controllerSpecificFilters = OrderFilters(actionDescriptor.ControllerDescriptor.GetFilters(), FilterScope.Controller);

    // action-specific
    IEnumerable<FilterInfo> actionSpecificFilters = OrderFilters(actionDescriptor.GetFilters(), FilterScope.Action);

    return controllerSpecificFilters.Concat(actionSpecificFilters);
    }

    private IEnumerable<FilterInfo> OrderFilters(IEnumerable<IFilter> filters, FilterScope scope)
    {
    return filters.OfType<IOrderedFilter>()
    .OrderBy(filter => filter.Order)
    .Select(instance => new FilterInfo(instance, scope));
    }
    }

    //NOTE: Here I am creating base attributes which you would need to inherit from.
    public interface IOrderedFilter : IFilter
    {
    int Order { get; set; }
    }

    public class ActionFilterWithOrderAttribute : ActionFilterAttribute, IOrderedFilter
    {
    public int Order { get; set; }
    }

    public class AuthorizationFilterWithOrderAttribute : AuthorizationFilterAttribute, IOrderedFilter
    {
    public int Order { get; set; }
    }

    public class ExceptionFilterWithOrderAttribute : ExceptionFilterAttribute, IOrderedFilter
    {
    public int Order { get; set; }
    }

Multiple ActionFilterAttribute order of execution assured?

I had the solution proposed above working as such:

Your custom attributes have to inherit:

public class LoginAttribute : ActionFilterWithOrderAttribute
{

}

public class UserRoleAttribute : ActionFilterWithOrderAttribute
{

}

And a method wanting to use it should be decorated as:

[Common.PortalSecurity.Login(Order=1)]
[Common.PortalSecurity.UserRole(Order=2)]
public HttpResponseMessage GetAll(string sessionToken)
{
return new HttpResponseMessage();
}

Action filter execution order

This is a long shot, but have you tried using the Global and First values for your FirstAuthorizeAttribute ?

http://msdn.microsoft.com/en-us/library/system.web.mvc.filterscope(v=vs.98).aspx

http://blog.rajsoftware.com/post/2011/05/14/MVC3-Filter-Ordering.aspx

In what order are filters executed in asp.net mvc

Filters run in the following order:

  1. Authorization filters
  2. Action filters
  3. Response filters
  4. Exception filters

For example, authorization filters run first and exception filters run last. Within each filter type, the Order value specifies the run order. Within each filter type and order, the Scope enumeration value specifies the order for filters. This enumeration defines the following filter scope values (in the order in which they run):

  1. First
  2. Global
  3. Controller
  4. Action
  5. Last

Extracted from MSDN



Related Topics



Leave a reply



Submit