diff --git a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs index 3d40e3d855..b7c582235a 100644 --- a/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Core/DefaultControllerFactory.cs @@ -1,6 +1,6 @@ using System; -using System.Reflection; using Microsoft.AspNet.DependencyInjection; +using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.ModelBinding; using Microsoft.AspNet.Mvc.Rendering; @@ -22,23 +22,18 @@ namespace Microsoft.AspNet.Mvc var actionDescriptor = actionContext.ActionDescriptor as ReflectedActionDescriptor; 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) - InitializeController(controller, actionContext); + // TODO: How do we feed the controller with context (need DI improvements) + InitializeController(controller, actionContext); - return controller; - } // TODO: Should we not catch it here? - catch (ReflectionTypeLoadException) - { - } - - return null; + return controller; } public void ReleaseController(object controller) diff --git a/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs index 9e54509e08..862d4280d6 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Mvc.Core/Properties/Resources.Designer.cs @@ -201,7 +201,7 @@ namespace Microsoft.AspNet.Mvc.Core { return string.Format(CultureInfo.CurrentCulture, GetString("ViewComponent_InvalidReturnValue"), p0, p1, p2); } - + /// /// Replacing the action context is not supported. /// @@ -234,6 +234,54 @@ namespace Microsoft.AspNet.Mvc.Core return string.Format(CultureInfo.CurrentCulture, GetString("ActionInvokerFactory_CouldNotCreateInvoker"), p0); } + /// + /// The action descriptor must be of type '{0}'. + /// + internal static string DefaultControllerFactory_ActionDescriptorMustBeReflected + { + get { return GetString("DefaultControllerFactory_ActionDescriptorMustBeReflected"); } + } + + /// + /// The action descriptor must be of type '{0}'. + /// + internal static string FormatDefaultControllerFactory_ActionDescriptorMustBeReflected(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("DefaultControllerFactory_ActionDescriptorMustBeReflected"), p0); + } + + /// + /// The '{0}' property of '{1}' must not be null. + /// + internal static string PropertyOfTypeCannotBeNull + { + get { return GetString("PropertyOfTypeCannotBeNull"); } + } + + /// + /// The '{0}' property of '{1}' must not be null. + /// + internal static string FormatPropertyOfTypeCannotBeNull(object p0, object p1) + { + return string.Format(CultureInfo.CurrentCulture, GetString("PropertyOfTypeCannotBeNull"), p0, p1); + } + + /// + /// The '{0}' must return a non null '{1}'. + /// + internal static string MethodMustReturnNotNullValue + { + get { return GetString("MethodMustReturnNotNullValue"); } + } + + /// + /// The '{0}' must return a non null '{1}'. + /// + 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) { var value = _resourceManager.GetString(name); diff --git a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs index f955187d02..9e5b31701a 100644 --- a/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc.Core/ReflectedActionInvoker.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNet.DependencyInjection; +using Microsoft.AspNet.Mvc.Core; using Microsoft.AspNet.Mvc.Filters; using Microsoft.AspNet.Mvc.ModelBinding; @@ -21,12 +23,12 @@ namespace Microsoft.AspNet.Mvc private readonly List _actionFilters = new List(); private readonly List _actionResultFilters = new List(); - public ReflectedActionInvoker(ActionContext actionContext, - ReflectedActionDescriptor descriptor, - IActionResultFactory actionResultFactory, - IControllerFactory controllerFactory, - IActionBindingContextProvider bindingContextProvider, - INestedProviderManager filterProvider) + public ReflectedActionInvoker([NotNull] ActionContext actionContext, + [NotNull] ReflectedActionDescriptor descriptor, + [NotNull] IActionResultFactory actionResultFactory, + [NotNull] IControllerFactory controllerFactory, + [NotNull] IActionBindingContextProvider bindingContextProvider, + [NotNull] INestedProviderManager filterProvider) { _actionContext = actionContext; _descriptor = descriptor; @@ -34,6 +36,14 @@ namespace Microsoft.AspNet.Mvc _controllerFactory = controllerFactory; _bindingProvider = bindingContextProvider; _filterProvider = filterProvider; + + if (descriptor.MethodInfo == null) + { + throw new ArgumentException( + Resources.FormatPropertyOfTypeCannotBeNull(typeof(ReflectedActionDescriptor), + "MethodInfo"), + "descriptor"); + } } public async Task InvokeActionAsync() @@ -54,67 +64,56 @@ namespace Microsoft.AspNet.Mvc if (controller == null) { - // TODO: See if these return 404s should turn into 500s - actionResult = new HttpStatusCodeResult(404); + throw new InvalidOperationException( + 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(_authorizationFilters, authZContext); + + await authZPipeline.InvokeAsync(); + + if (authZContext.ActionResult == null && + !authZContext.HasFailed && + authZEndPoint.EndPointCalled) { - // TODO: See if these return 404s should turn into 500s - actionResult = new HttpStatusCodeResult(404); + actionResult = null; } else { - if (_authorizationFilters.Count > 0) - { - var authZEndPoint = new AuthorizationFilterEndPoint(); - _authorizationFilters.Add(authZEndPoint); - - var authZContext = new AuthorizationFilterContext(_actionContext, filterMetaItems); - var authZPipeline = new FilterPipelineBuilder(_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(_actionFilters, - actionFilterContext); - - await actionFilterPipeline.InvokeAsync(); - - actionResult = actionFilterContext.ActionResult; - } + // 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(_actionFilters, + actionFilterContext); + + await actionFilterPipeline.InvokeAsync(); + + actionResult = actionFilterContext.ActionResult; + } var actionResultFilterContext = new ActionResultFilterContext(_actionContext, filterMetaItems, actionResult); var actionResultFilterEndPoint = new ActionResultFilterEndPoint(); diff --git a/src/Microsoft.AspNet.Mvc.Core/Resources.resx b/src/Microsoft.AspNet.Mvc.Core/Resources.resx index 86c20a3c52..0921753a93 100644 --- a/src/Microsoft.AspNet.Mvc.Core/Resources.resx +++ b/src/Microsoft.AspNet.Mvc.Core/Resources.resx @@ -159,4 +159,13 @@ An action invoker could not be created for action '{0}'. + + The action descriptor must be of type '{0}'. + + + The '{0}' property of '{1}' must not be null. + + + The '{0}' must return a non null '{1}'. +