Order of execution with multiple filters in web api
Some things to note here:
- Filters get executed in the following order for an action: Globally
Defined Filters -> Controller-specific Filters -> Action-specific Filters. - Authorization Filters -> Action Filters -> Exception
Filters Now the problem that you seem to mention is related to
having multiple filters of the same kind (ex: MultipleActionFilterAttribute
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 ofSystem.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:
- Authorization filters
- Action filters
- Response filters
- 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):
- First
- Global
- Controller
- Action
- Last
Extracted from MSDN
Related Topics
General Advice and Guidelines on How to Properly Override Object.Gethashcode()
In C# What Category Does the Colon ":" Fall Into, and What Does It Really Mean
Udp Hole Punching Implementation
Restoring Window Size/Position with Multiple Monitors
Extract Thumbnail for Any File in Windows
How to Download/Upload Files From/To Sharepoint 2013 Using Csom
How to Bind to a Dynamicresource So You Can Use a Converter or Stringformat, etc.? (Revision 4)
How to Use Custom Authorize Attribute for Roles as Well as a Specific User
How to Use Acrylic Accent in Windows 10 Creators Update
Reference a .Net Core Library in a .Net 4.6 Project
Get Datetime.Now with Milliseconds Precision
Recommend a C# Task Scheduling Library
Convert List to Dictionary Using Linq and Not Worrying About Duplicates
Why Is a Round-Trip Conversion via a String Not Safe for a Double