diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/DefaultFilterProvider.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/DefaultFilterProvider.cs index c873d8826b..a2169ae0f9 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Filters/DefaultFilterProvider.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Filters/DefaultFilterProvider.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Diagnostics.Contracts; using Microsoft.AspNet.DependencyInjection; @@ -26,9 +25,9 @@ namespace Microsoft.AspNet.Mvc.Filters // make a copy of the list, TODO: Make the actiondescriptor immutable var filterDescriptors = context.ActionDescriptor.FilterDescriptors.ToArray(); - for (int i = 0; i < filterDescriptors.Length; i++) + foreach (var item in context.Items) { - ProvideFilter(context, filterDescriptors[i].Filter); + ProvideFilter(context, item); } } @@ -38,9 +37,16 @@ namespace Microsoft.AspNet.Mvc.Filters } } - public virtual void ProvideFilter(FilterProviderContext context, IFilter filter) + public virtual void ProvideFilter(FilterProviderContext context, FilterProviderContext.FilterItem filterItem) { - var serviceFilterSignature = filter as IServiceFilter; + var filter = filterItem.Filter; + + if (filter != null) + { + return; + } + + var serviceFilterSignature = filterItem.Descriptor.Filter as IServiceFilter; if (serviceFilterSignature != null) { var serviceFilter = ServiceProvider.GetService(serviceFilterSignature.ServiceType) as IFilter; @@ -50,12 +56,11 @@ namespace Microsoft.AspNet.Mvc.Filters throw new InvalidOperationException("Service filter must be of type IFilter"); } - ApplyFilterToContainer(serviceFilter, filter); - AddFilters(context, serviceFilter); + filterItem.Filter = serviceFilter; } else { - var typeFilterSignature = filter as ITypeFilter; + var typeFilterSignature = filterItem.Descriptor.Filter as ITypeFilter; if (typeFilterSignature != null) { if (typeFilterSignature.ImplementationType == null) @@ -72,25 +77,15 @@ namespace Microsoft.AspNet.Mvc.Filters var typeFilter = ActivatorUtilities.CreateInstance(ServiceProvider, typeFilterSignature.ImplementationType) as IFilter; ApplyFilterToContainer(typeFilter, filter); - AddFilters(context, typeFilter); + filterItem.Filter = typeFilter; } else { - AddFilters(context, filter); + filterItem.Filter = filter; } } } - private void AddFilters(FilterProviderContext context, IFilter filter) - { - if (context.OrderedFilterList == null) - { - context.OrderedFilterList = new List(); - } - - context.OrderedFilterList.Add(filter); - } - private void ApplyFilterToContainer(object actualFilter, IFilter filterMetadata) { Contract.Assert(actualFilter != null, "actualFilter should not be null"); diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/FilterProviderContext.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/FilterProviderContext.cs index a6b6e2b5c7..6319ac6297 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Filters/FilterProviderContext.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Filters/FilterProviderContext.cs @@ -4,15 +4,33 @@ namespace Microsoft.AspNet.Mvc { public class FilterProviderContext { - public FilterProviderContext(ActionDescriptor actionDescriptor) + public FilterProviderContext(ActionDescriptor actionDescriptor, List items) { ActionDescriptor = actionDescriptor; + Items = items; } // Input public ActionDescriptor ActionDescriptor { get; set; } // Result - public List OrderedFilterList { get; set; } + public List Items { get; set; } + + public class FilterItem + { + public FilterItem([NotNull] FilterDescriptor descriptor) + { + Descriptor = descriptor; + } + + public FilterItem([NotNull] FilterDescriptor descriptor, [NotNull] IFilter filter) : this(descriptor) + { + Filter = filter; + } + + public FilterDescriptor Descriptor { get; set; } + + public IFilter Filter { get; set; } + } } } diff --git a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs index bda2832ad4..54a118ceb5 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Microsoft.AspNet.DependencyInjection; using Microsoft.AspNet.Mvc.Filters; @@ -39,9 +40,15 @@ namespace Microsoft.AspNet.Mvc public async Task InvokeActionAsync() { IActionResult actionResult; - var filterProviderContext = new FilterProviderContext(_descriptor); + var filterProviderContext = + new FilterProviderContext(_descriptor, + _descriptor. + FilterDescriptors. + Select(fd => new FilterProviderContext.FilterItem(fd)).ToList()); + _filterProvider.Invoke(filterProviderContext); + // TODO: arrange when needed. PreArrangeFiltersInPipeline(filterProviderContext); var modelState = new ModelStateDictionary(); @@ -61,8 +68,6 @@ namespace Microsoft.AspNet.Mvc } else { - var parameterValues = await GetParameterValues(modelState); - if (_authorizationFilters.Count > 0) { var authZEndPoint = new AuthorizationFilterEndPoint(); @@ -92,6 +97,8 @@ namespace Microsoft.AspNet.Mvc if (actionResult == null) { + var parameterValues = await GetParameterValues(modelState); + var actionFilterContext = new ActionFilterContext(_actionContext, parameterValues, method.ReturnType); @@ -153,12 +160,12 @@ namespace Microsoft.AspNet.Mvc private void PreArrangeFiltersInPipeline(FilterProviderContext context) { - if (context.OrderedFilterList == null || context.OrderedFilterList.Count == 0) + if (context.Items == null || context.Items.Count == 0) { return; } - foreach (var filter in context.OrderedFilterList) + foreach (var filter in context.Items) { PlaceFilter(filter); }