Action invocation changes:
Changed 404s to throw Propagate reflected exception Add resources for specific errors
This commit is contained in:
parent
1b4754454b
commit
9756f74565
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.AspNet.DependencyInjection;
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using Microsoft.AspNet.Mvc.Core;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
using Microsoft.AspNet.Mvc.Rendering;
|
using Microsoft.AspNet.Mvc.Rendering;
|
||||||
|
|
||||||
|
|
@ -22,23 +22,18 @@ namespace Microsoft.AspNet.Mvc
|
||||||
var actionDescriptor = actionContext.ActionDescriptor as ReflectedActionDescriptor;
|
var actionDescriptor = actionContext.ActionDescriptor as ReflectedActionDescriptor;
|
||||||
if (actionDescriptor == null)
|
if (actionDescriptor == null)
|
||||||
{
|
{
|
||||||
return null;
|
throw new ArgumentException(
|
||||||
|
Resources.FormatDefaultControllerFactory_ActionDescriptorMustBeReflected(
|
||||||
|
typeof(ReflectedActionDescriptor)),
|
||||||
|
"actionContext");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
var controller = _activator.CreateInstance(_serviceProvider, actionDescriptor.ControllerDescriptor.ControllerTypeInfo.AsType());
|
||||||
{
|
|
||||||
var controller = _activator.CreateInstance(_serviceProvider, actionDescriptor.ControllerDescriptor.ControllerTypeInfo.AsType());
|
|
||||||
|
|
||||||
// TODO: How do we feed the controller with context (need DI improvements)
|
// TODO: How do we feed the controller with context (need DI improvements)
|
||||||
InitializeController(controller, actionContext);
|
InitializeController(controller, actionContext);
|
||||||
|
|
||||||
return controller;
|
return controller;
|
||||||
} // TODO: Should we not catch it here?
|
|
||||||
catch (ReflectionTypeLoadException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReleaseController(object controller)
|
public void ReleaseController(object controller)
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ namespace Microsoft.AspNet.Mvc.Core
|
||||||
{
|
{
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_InvalidReturnValue"), p0, p1, p2);
|
return string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_InvalidReturnValue"), p0, p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Replacing the action context is not supported.
|
/// Replacing the action context is not supported.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -234,6 +234,54 @@ namespace Microsoft.AspNet.Mvc.Core
|
||||||
return string.Format(CultureInfo.CurrentCulture, GetString("ActionInvokerFactory_CouldNotCreateInvoker"), p0);
|
return string.Format(CultureInfo.CurrentCulture, GetString("ActionInvokerFactory_CouldNotCreateInvoker"), p0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The action descriptor must be of type '{0}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string DefaultControllerFactory_ActionDescriptorMustBeReflected
|
||||||
|
{
|
||||||
|
get { return GetString("DefaultControllerFactory_ActionDescriptorMustBeReflected"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The action descriptor must be of type '{0}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatDefaultControllerFactory_ActionDescriptorMustBeReflected(object p0)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("DefaultControllerFactory_ActionDescriptorMustBeReflected"), p0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The '{0}' property of '{1}' must not be null.
|
||||||
|
/// </summary>
|
||||||
|
internal static string PropertyOfTypeCannotBeNull
|
||||||
|
{
|
||||||
|
get { return GetString("PropertyOfTypeCannotBeNull"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The '{0}' property of '{1}' must not be null.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatPropertyOfTypeCannotBeNull(object p0, object p1)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("PropertyOfTypeCannotBeNull"), p0, p1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The '{0}' must return a non null '{1}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string MethodMustReturnNotNullValue
|
||||||
|
{
|
||||||
|
get { return GetString("MethodMustReturnNotNullValue"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The '{0}' must return a non null '{1}'.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatMethodMustReturnNotNullValue(object p0, object p1)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("MethodMustReturnNotNullValue"), p0, p1);
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetString(string name, params string[] formatterNames)
|
private static string GetString(string name, params string[] formatterNames)
|
||||||
{
|
{
|
||||||
var value = _resourceManager.GetString(name);
|
var value = _resourceManager.GetString(name);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.DependencyInjection;
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using Microsoft.AspNet.Mvc.Core;
|
||||||
using Microsoft.AspNet.Mvc.Filters;
|
using Microsoft.AspNet.Mvc.Filters;
|
||||||
using Microsoft.AspNet.Mvc.ModelBinding;
|
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||||
|
|
||||||
|
|
@ -21,12 +23,12 @@ namespace Microsoft.AspNet.Mvc
|
||||||
private readonly List<IActionFilter> _actionFilters = new List<IActionFilter>();
|
private readonly List<IActionFilter> _actionFilters = new List<IActionFilter>();
|
||||||
private readonly List<IActionResultFilter> _actionResultFilters = new List<IActionResultFilter>();
|
private readonly List<IActionResultFilter> _actionResultFilters = new List<IActionResultFilter>();
|
||||||
|
|
||||||
public ReflectedActionInvoker(ActionContext actionContext,
|
public ReflectedActionInvoker([NotNull] ActionContext actionContext,
|
||||||
ReflectedActionDescriptor descriptor,
|
[NotNull] ReflectedActionDescriptor descriptor,
|
||||||
IActionResultFactory actionResultFactory,
|
[NotNull] IActionResultFactory actionResultFactory,
|
||||||
IControllerFactory controllerFactory,
|
[NotNull] IControllerFactory controllerFactory,
|
||||||
IActionBindingContextProvider bindingContextProvider,
|
[NotNull] IActionBindingContextProvider bindingContextProvider,
|
||||||
INestedProviderManager<FilterProviderContext> filterProvider)
|
[NotNull] INestedProviderManager<FilterProviderContext> filterProvider)
|
||||||
{
|
{
|
||||||
_actionContext = actionContext;
|
_actionContext = actionContext;
|
||||||
_descriptor = descriptor;
|
_descriptor = descriptor;
|
||||||
|
|
@ -34,6 +36,14 @@ namespace Microsoft.AspNet.Mvc
|
||||||
_controllerFactory = controllerFactory;
|
_controllerFactory = controllerFactory;
|
||||||
_bindingProvider = bindingContextProvider;
|
_bindingProvider = bindingContextProvider;
|
||||||
_filterProvider = filterProvider;
|
_filterProvider = filterProvider;
|
||||||
|
|
||||||
|
if (descriptor.MethodInfo == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
Resources.FormatPropertyOfTypeCannotBeNull(typeof(ReflectedActionDescriptor),
|
||||||
|
"MethodInfo"),
|
||||||
|
"descriptor");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task InvokeActionAsync()
|
public async Task InvokeActionAsync()
|
||||||
|
|
@ -54,67 +64,56 @@ namespace Microsoft.AspNet.Mvc
|
||||||
|
|
||||||
if (controller == null)
|
if (controller == null)
|
||||||
{
|
{
|
||||||
// TODO: See if these return 404s should turn into 500s
|
throw new InvalidOperationException(
|
||||||
actionResult = new HttpStatusCodeResult(404);
|
Resources.FormatMethodMustReturnNotNullValue(typeof(IControllerFactory),
|
||||||
|
"controller"));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
var method = _descriptor.MethodInfo;
|
|
||||||
|
|
||||||
if (method == null)
|
if (_authorizationFilters.Count > 0)
|
||||||
|
{
|
||||||
|
var authZEndPoint = new AuthorizationFilterEndPoint();
|
||||||
|
_authorizationFilters.Add(authZEndPoint);
|
||||||
|
|
||||||
|
var authZContext = new AuthorizationFilterContext(_actionContext, filterMetaItems);
|
||||||
|
var authZPipeline = new FilterPipelineBuilder<AuthorizationFilterContext>(_authorizationFilters, authZContext);
|
||||||
|
|
||||||
|
await authZPipeline.InvokeAsync();
|
||||||
|
|
||||||
|
if (authZContext.ActionResult == null &&
|
||||||
|
!authZContext.HasFailed &&
|
||||||
|
authZEndPoint.EndPointCalled)
|
||||||
{
|
{
|
||||||
// TODO: See if these return 404s should turn into 500s
|
actionResult = null;
|
||||||
actionResult = new HttpStatusCodeResult(404);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_authorizationFilters.Count > 0)
|
// User cleaned out the result but we failed or short circuited the end point.
|
||||||
{
|
actionResult = authZContext.ActionResult ?? new HttpStatusCodeResult(401);
|
||||||
var authZEndPoint = new AuthorizationFilterEndPoint();
|
|
||||||
_authorizationFilters.Add(authZEndPoint);
|
|
||||||
|
|
||||||
var authZContext = new AuthorizationFilterContext(_actionContext, filterMetaItems);
|
|
||||||
var authZPipeline = new FilterPipelineBuilder<AuthorizationFilterContext>(_authorizationFilters, authZContext);
|
|
||||||
|
|
||||||
await authZPipeline.InvokeAsync();
|
|
||||||
|
|
||||||
if (authZContext.ActionResult == null &&
|
|
||||||
!authZContext.HasFailed &&
|
|
||||||
authZEndPoint.EndPointCalled)
|
|
||||||
{
|
|
||||||
actionResult = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// User cleaned out the result but we failed or short circuited the end point.
|
|
||||||
actionResult = 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<ActionFilterContext>(_actionFilters,
|
|
||||||
actionFilterContext);
|
|
||||||
|
|
||||||
await actionFilterPipeline.InvokeAsync();
|
|
||||||
|
|
||||||
actionResult = actionFilterContext.ActionResult;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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<ActionFilterContext>(_actionFilters,
|
||||||
|
actionFilterContext);
|
||||||
|
|
||||||
|
await actionFilterPipeline.InvokeAsync();
|
||||||
|
|
||||||
|
actionResult = actionFilterContext.ActionResult;
|
||||||
|
}
|
||||||
|
|
||||||
var actionResultFilterContext = new ActionResultFilterContext(_actionContext, filterMetaItems, actionResult);
|
var actionResultFilterContext = new ActionResultFilterContext(_actionContext, filterMetaItems, actionResult);
|
||||||
var actionResultFilterEndPoint = new ActionResultFilterEndPoint();
|
var actionResultFilterEndPoint = new ActionResultFilterEndPoint();
|
||||||
|
|
|
||||||
|
|
@ -159,4 +159,13 @@
|
||||||
<data name="ActionInvokerFactory_CouldNotCreateInvoker" xml:space="preserve">
|
<data name="ActionInvokerFactory_CouldNotCreateInvoker" xml:space="preserve">
|
||||||
<value>An action invoker could not be created for action '{0}'.</value>
|
<value>An action invoker could not be created for action '{0}'.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DefaultControllerFactory_ActionDescriptorMustBeReflected" xml:space="preserve">
|
||||||
|
<value>The action descriptor must be of type '{0}'.</value>
|
||||||
|
</data>
|
||||||
|
<data name="PropertyOfTypeCannotBeNull" xml:space="preserve">
|
||||||
|
<value>The '{0}' property of '{1}' must not be null.</value>
|
||||||
|
</data>
|
||||||
|
<data name="MethodMustReturnNotNullValue" xml:space="preserve">
|
||||||
|
<value>The '{0}' must return a non null '{1}'.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue