diff --git a/src/Microsoft.AspNet.Mvc.Core/Filters/AuthorizationFilterEndPoint.cs b/src/Microsoft.AspNet.Mvc.Core/Filters/AuthorizationFilterEndPoint.cs index 910cfe0479..8d42516404 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Filters/AuthorizationFilterEndPoint.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Filters/AuthorizationFilterEndPoint.cs @@ -6,11 +6,11 @@ namespace Microsoft.AspNet.Mvc.Filters // This one lives in the Filters namespace, and only intended to be consumed by folks that rewrite the action invoker. public class AuthorizationFilterEndPoint : IAuthorizationFilter { - public bool EndPointCalled { get; private set; } + public bool WasEndPointCalled { get; private set; } public Task Invoke(AuthorizationFilterContext context, Func next) { - EndPointCalled = true; + WasEndPointCalled = true; return Task.FromResult(true); } diff --git a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs index 9e5b31701a..515616197b 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs @@ -49,6 +49,26 @@ namespace Microsoft.AspNet.Mvc public async Task InvokeActionAsync() { IActionResult actionResult; + + var filterMetaItems = GetAndArrangeFilters(); + + var controller = _controllerFactory.CreateController(_actionContext); + + if (controller == null) + { + throw new InvalidOperationException( + Resources.FormatMethodMustReturnNotNullValue(typeof(IControllerFactory), + "controller")); + } + + actionResult = await RunAuthorizationFilters(filterMetaItems) ?? + await RunActionFiltersAndActions(filterMetaItems, controller); + + await RunActionResultFilters(actionResult, filterMetaItems); + } + + private FilterItem[] GetAndArrangeFilters() + { var filterProviderContext = new FilterProviderContext(_descriptor, _descriptor. @@ -60,15 +80,11 @@ namespace Microsoft.AspNet.Mvc PreArrangeFiltersInPipeline(filterProviderContext); - var controller = _controllerFactory.CreateController(_actionContext); - - if (controller == null) - { - throw new InvalidOperationException( - Resources.FormatMethodMustReturnNotNullValue(typeof(IControllerFactory), - "controller")); - } + return filterMetaItems; + } + private async Task RunAuthorizationFilters(FilterItem[] filterMetaItems) + { if (_authorizationFilters.Count > 0) { var authZEndPoint = new AuthorizationFilterEndPoint(); @@ -81,47 +97,14 @@ namespace Microsoft.AspNet.Mvc if (authZContext.ActionResult == null && !authZContext.HasFailed && - authZEndPoint.EndPointCalled) - { - actionResult = null; - } - else + authZEndPoint.WasEndPointCalled) { // User cleaned out the result but we failed or short circuited the end point. - actionResult = authZContext.ActionResult ?? new HttpStatusCodeResult(401); + return authZContext.ActionResult ?? new HttpStatusCodeResult(401); } } - else - { - actionResult = null; - } - if (actionResult == null) - { - var parameterValues = await GetParameterValues(_actionContext.ModelState); - - var actionFilterContext = new ActionFilterContext(_actionContext, - filterMetaItems, - parameterValues); - - var actionEndPoint = new ReflectedActionFilterEndPoint(_actionResultFactory, controller); - - _actionFilters.Add(actionEndPoint); - var actionFilterPipeline = new FilterPipelineBuilder(_actionFilters, - actionFilterContext); - - await actionFilterPipeline.InvokeAsync(); - - actionResult = actionFilterContext.ActionResult; - } - - var actionResultFilterContext = new ActionResultFilterContext(_actionContext, filterMetaItems, actionResult); - var actionResultFilterEndPoint = new ActionResultFilterEndPoint(); - _actionResultFilters.Add(actionResultFilterEndPoint); - - var actionResultPipeline = new FilterPipelineBuilder(_actionResultFilters, actionResultFilterContext); - - await actionResultPipeline.InvokeAsync(); + return null; } private async Task> GetParameterValues(ModelStateDictionary modelState) @@ -176,6 +159,37 @@ namespace Microsoft.AspNet.Mvc return parameterValues; } + private async Task RunActionFiltersAndActions(FilterItem[] filterMetaItems, object controller) + { + var parameterValues = await GetParameterValues(_actionContext.ModelState); + + var actionFilterContext = new ActionFilterContext(_actionContext, + filterMetaItems, + parameterValues); + + var actionEndPoint = new ReflectedActionFilterEndPoint(_actionResultFactory, controller); + + _actionFilters.Add(actionEndPoint); + var actionFilterPipeline = new FilterPipelineBuilder(_actionFilters, + actionFilterContext); + + await actionFilterPipeline.InvokeAsync(); + + return actionFilterContext.ActionResult; + } + + private async Task RunActionResultFilters(IActionResult actionResult, FilterItem[] filterMetaItems) + { + var actionResultFilterContext = new ActionResultFilterContext(_actionContext, filterMetaItems, actionResult); + var actionResultFilterEndPoint = new ActionResultFilterEndPoint(); + _actionResultFilters.Add(actionResultFilterEndPoint); + + var actionResultPipeline = new FilterPipelineBuilder(_actionResultFilters, + actionResultFilterContext); + + await actionResultPipeline.InvokeAsync(); + } + private void PreArrangeFiltersInPipeline(FilterProviderContext context) { if (context.Result == null || context.Result.Count == 0) diff --git a/src/Microsoft.AspNet.Mvc.Core/Resources.resx b/src/Microsoft.AspNet.Mvc.Core/Resources.resx index 0921753a93..7698b726e2 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Resources.resx +++ b/src/Microsoft.AspNet.Mvc.Core/Resources.resx @@ -166,6 +166,6 @@ The '{0}' property of '{1}' must not be null. - The '{0}' must return a non null '{1}'. + The '{0}' must return a non-null '{1}'.