Factor filters action to private methods

This commit is contained in:
Yishai Galatzer 2014-04-01 10:39:18 -07:00
parent 9756f74565
commit d081300185
3 changed files with 61 additions and 47 deletions

View File

@ -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. // 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 class AuthorizationFilterEndPoint : IAuthorizationFilter
{ {
public bool EndPointCalled { get; private set; } public bool WasEndPointCalled { get; private set; }
public Task Invoke(AuthorizationFilterContext context, Func<Task> next) public Task Invoke(AuthorizationFilterContext context, Func<Task> next)
{ {
EndPointCalled = true; WasEndPointCalled = true;
return Task.FromResult(true); return Task.FromResult(true);
} }

View File

@ -49,6 +49,26 @@ namespace Microsoft.AspNet.Mvc
public async Task InvokeActionAsync() public async Task InvokeActionAsync()
{ {
IActionResult actionResult; 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 = var filterProviderContext =
new FilterProviderContext(_descriptor, new FilterProviderContext(_descriptor,
_descriptor. _descriptor.
@ -60,15 +80,11 @@ namespace Microsoft.AspNet.Mvc
PreArrangeFiltersInPipeline(filterProviderContext); PreArrangeFiltersInPipeline(filterProviderContext);
var controller = _controllerFactory.CreateController(_actionContext); return filterMetaItems;
}
if (controller == null)
{
throw new InvalidOperationException(
Resources.FormatMethodMustReturnNotNullValue(typeof(IControllerFactory),
"controller"));
}
private async Task<IActionResult> RunAuthorizationFilters(FilterItem[] filterMetaItems)
{
if (_authorizationFilters.Count > 0) if (_authorizationFilters.Count > 0)
{ {
var authZEndPoint = new AuthorizationFilterEndPoint(); var authZEndPoint = new AuthorizationFilterEndPoint();
@ -81,47 +97,14 @@ namespace Microsoft.AspNet.Mvc
if (authZContext.ActionResult == null && if (authZContext.ActionResult == null &&
!authZContext.HasFailed && !authZContext.HasFailed &&
authZEndPoint.EndPointCalled) authZEndPoint.WasEndPointCalled)
{
actionResult = null;
}
else
{ {
// User cleaned out the result but we failed or short circuited the end point. // 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) return 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<ActionFilterContext>(_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<ActionResultFilterContext>(_actionResultFilters, actionResultFilterContext);
await actionResultPipeline.InvokeAsync();
} }
private async Task<IDictionary<string, object>> GetParameterValues(ModelStateDictionary modelState) private async Task<IDictionary<string, object>> GetParameterValues(ModelStateDictionary modelState)
@ -176,6 +159,37 @@ namespace Microsoft.AspNet.Mvc
return parameterValues; return parameterValues;
} }
private async Task<IActionResult> 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<ActionFilterContext>(_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<ActionResultFilterContext>(_actionResultFilters,
actionResultFilterContext);
await actionResultPipeline.InvokeAsync();
}
private void PreArrangeFiltersInPipeline(FilterProviderContext context) private void PreArrangeFiltersInPipeline(FilterProviderContext context)
{ {
if (context.Result == null || context.Result.Count == 0) if (context.Result == null || context.Result.Count == 0)

View File

@ -166,6 +166,6 @@
<value>The '{0}' property of '{1}' must not be null.</value> <value>The '{0}' property of '{1}' must not be null.</value>
</data> </data>
<data name="MethodMustReturnNotNullValue" xml:space="preserve"> <data name="MethodMustReturnNotNullValue" xml:space="preserve">
<value>The '{0}' must return a non null '{1}'.</value> <value>The '{0}' must return a non-null '{1}'.</value>
</data> </data>
</root> </root>