From a725e4c9b56b43822c43437af88f86c15fa77f4f Mon Sep 17 00:00:00 2001 From: Yishai Galatzer Date: Sat, 8 Feb 2014 09:33:13 -0800 Subject: [PATCH] Update to support 404 Renamed actiondescriptor to routecontext, because action selection didn't happen yet. Need to add actiondescriptors back and modify RazorViewEngine to use the right thing. --- samples/MvcSample/Home2Controller.cs | 2 +- .../ViewEngine/RazorViewEngine.cs | 6 ++-- .../MvcServices.cs | 3 +- src/Microsoft.AspNet.Mvc/ActionDescriptor.cs | 7 ---- .../ActionDescriptorProvider.cs | 9 +++-- .../ActionInvokerFactory.cs | 10 +++--- .../ActionInvokerProvider.cs | 10 +++--- .../ControllerActionInvoker.cs | 35 ++++++++++--------- .../ControllerBasedActionDescriptor.cs | 5 ++- src/Microsoft.AspNet.Mvc/ControllerCache.cs | 1 - .../DefaultControllerCache.cs | 9 ++++- .../DefaultControllerFactory.cs | 16 ++++----- .../IActionDescriptorProvider.cs | 4 +-- .../IActionInvokerProvider.cs | 2 +- src/Microsoft.AspNet.Mvc/RouteContext.cs | 6 ++++ 15 files changed, 65 insertions(+), 60 deletions(-) delete mode 100644 src/Microsoft.AspNet.Mvc/ActionDescriptor.cs create mode 100644 src/Microsoft.AspNet.Mvc/RouteContext.cs diff --git a/samples/MvcSample/Home2Controller.cs b/samples/MvcSample/Home2Controller.cs index 9ce16357e5..2ebf8333d2 100644 --- a/samples/MvcSample/Home2Controller.cs +++ b/samples/MvcSample/Home2Controller.cs @@ -19,7 +19,7 @@ namespace MvcSample.RandomNameSpace public string Index() { - return "Hello World"; + return "Hello World: my namespace is " + this.GetType().Namespace; } public IActionResult Something() diff --git a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/RazorViewEngine.cs b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/RazorViewEngine.cs index 694acfa1ac..443686a63a 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/RazorViewEngine.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/ViewEngine/RazorViewEngine.cs @@ -12,10 +12,10 @@ namespace Microsoft.AspNet.Mvc.Razor "/Views/{1}/{0}.cshtml", "/Views/Shared/{0}.cshtml", }; - private readonly IActionDescriptorProvider _actionDescriptorProvider; + private readonly IRouteContextProvider _actionDescriptorProvider; private readonly IVirtualPathViewFactory _virtualPathFactory; - public RazorViewEngine(IActionDescriptorProvider actionDescriptorProvider, + public RazorViewEngine(IRouteContextProvider actionDescriptorProvider, IVirtualPathViewFactory virtualPathFactory) { _actionDescriptorProvider = actionDescriptorProvider; @@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Mvc.Razor public async Task FindView(RequestContext requestContext, string viewName) { - var actionDescriptor = _actionDescriptorProvider.CreateDescriptor(requestContext) as ControllerBasedActionDescriptor; + var actionDescriptor = _actionDescriptorProvider.CreateDescriptor(requestContext) as ControllerActionRouteContext; if (actionDescriptor == null) { diff --git a/src/Microsoft.AspNet.Mvc.Startup/MvcServices.cs b/src/Microsoft.AspNet.Mvc.Startup/MvcServices.cs index 5d6d717ea8..9fa0d2e7e9 100644 --- a/src/Microsoft.AspNet.Mvc.Startup/MvcServices.cs +++ b/src/Microsoft.AspNet.Mvc.Startup/MvcServices.cs @@ -21,12 +21,11 @@ namespace Microsoft.AspNet.Mvc.Startup { Services = new ServiceProvider(); - AddAndRegisterForFinalization(); AddAndRegisterForFinalization(); AddAndRegisterForFinalization(); AddAndRegisterForFinalization(); AddAndRegisterForFinalization(); - AddAndRegisterForFinalization(); + AddAndRegisterForFinalization(); AddAndRegisterForFinalization(); // need singleton support here. diff --git a/src/Microsoft.AspNet.Mvc/ActionDescriptor.cs b/src/Microsoft.AspNet.Mvc/ActionDescriptor.cs deleted file mode 100644 index 9ac4689922..0000000000 --- a/src/Microsoft.AspNet.Mvc/ActionDescriptor.cs +++ /dev/null @@ -1,7 +0,0 @@ - -namespace Microsoft.AspNet.Mvc -{ - public class ActionDescriptor - { - } -} diff --git a/src/Microsoft.AspNet.Mvc/ActionDescriptorProvider.cs b/src/Microsoft.AspNet.Mvc/ActionDescriptorProvider.cs index 06dc0c3449..57d48a794e 100644 --- a/src/Microsoft.AspNet.Mvc/ActionDescriptorProvider.cs +++ b/src/Microsoft.AspNet.Mvc/ActionDescriptorProvider.cs @@ -1,14 +1,13 @@ - -namespace Microsoft.AspNet.Mvc +namespace Microsoft.AspNet.Mvc { - public class ActionDescriptorProvider : IActionDescriptorProvider + public class ControllerActionBasedRouteContextProvider : IRouteContextProvider { - public ActionDescriptor CreateDescriptor(RequestContext requestContext) + public RouteContext CreateDescriptor(RequestContext requestContext) { string controllerName = requestContext.RouteData.GetRouteValue("controller"); string actionName = requestContext.RouteData.GetRouteValue("action"); - return new ControllerBasedActionDescriptor + return new ControllerActionRouteContext { ControllerName = controllerName, ActionName = actionName diff --git a/src/Microsoft.AspNet.Mvc/ActionInvokerFactory.cs b/src/Microsoft.AspNet.Mvc/ActionInvokerFactory.cs index 94e37107ef..dde0127cd1 100644 --- a/src/Microsoft.AspNet.Mvc/ActionInvokerFactory.cs +++ b/src/Microsoft.AspNet.Mvc/ActionInvokerFactory.cs @@ -6,23 +6,23 @@ namespace Microsoft.AspNet.Mvc public class ActionInvokerFactory : IActionInvokerFactory { private readonly IActionResultFactory _actionResultFactory; - private readonly IActionDescriptorProvider _actionDescriptorProvider; private readonly IActionInvokerProvider _actionInvokerProvider; + private readonly IRouteContextProvider _routeContextProvider; public ActionInvokerFactory(IActionResultFactory actionResultFactory, - IActionDescriptorProvider actionDescriptorProvider, + IRouteContextProvider actionDescriptorProvider, IActionInvokerProvider actionInvokerProvider) { _actionResultFactory = actionResultFactory; - _actionDescriptorProvider = actionDescriptorProvider; + _routeContextProvider = actionDescriptorProvider; _actionInvokerProvider = actionInvokerProvider; } public IActionInvoker CreateInvoker(RequestContext requestContext) { - ActionDescriptor descriptor = _actionDescriptorProvider.CreateDescriptor(requestContext); + RouteContext routeContext = _routeContextProvider.CreateDescriptor(requestContext); - return _actionInvokerProvider.GetInvoker(requestContext, descriptor); + return _actionInvokerProvider.GetInvoker(requestContext, routeContext); } } } diff --git a/src/Microsoft.AspNet.Mvc/ActionInvokerProvider.cs b/src/Microsoft.AspNet.Mvc/ActionInvokerProvider.cs index 0707b1afa9..f1433b691a 100644 --- a/src/Microsoft.AspNet.Mvc/ActionInvokerProvider.cs +++ b/src/Microsoft.AspNet.Mvc/ActionInvokerProvider.cs @@ -7,20 +7,20 @@ namespace Microsoft.AspNet.Mvc { private readonly IActionResultFactory _actionResultFactory; private readonly IServiceProvider _serviceProvider; - private readonly IControllerFactory _controrllerFactory; + private readonly IControllerFactory _controllerFactory; public ActionInvokerProvider(IActionResultFactory actionResultFactory, IControllerFactory controllerFactory, IServiceProvider serviceProvider) { _actionResultFactory = actionResultFactory; - _controrllerFactory = controllerFactory; + _controllerFactory = controllerFactory; _serviceProvider = serviceProvider; } - public IActionInvoker GetInvoker(RequestContext requestContext, ActionDescriptor descriptor) + public IActionInvoker GetInvoker(RequestContext requestContext, RouteContext routeContext) { - var controllerActionDescriptor = descriptor as ControllerBasedActionDescriptor; + var controllerActionDescriptor = routeContext as ControllerActionRouteContext; if (controllerActionDescriptor != null) { @@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Mvc requestContext, controllerActionDescriptor, _actionResultFactory, - _controrllerFactory, + _controllerFactory, _serviceProvider); } diff --git a/src/Microsoft.AspNet.Mvc/ControllerActionInvoker.cs b/src/Microsoft.AspNet.Mvc/ControllerActionInvoker.cs index c6e9bcff79..575d6a2fbe 100644 --- a/src/Microsoft.AspNet.Mvc/ControllerActionInvoker.cs +++ b/src/Microsoft.AspNet.Mvc/ControllerActionInvoker.cs @@ -1,23 +1,21 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNet.Abstractions; -using Microsoft.AspNet.DependencyInjection; namespace Microsoft.AspNet.Mvc { public class ControllerActionInvoker : IActionInvoker { private readonly RequestContext _requestContext; - private readonly ControllerBasedActionDescriptor _descriptor; + private readonly ControllerActionRouteContext _descriptor; private readonly IActionResultFactory _actionResultFactory; private readonly IServiceProvider _serviceProvider; private readonly IControllerFactory _controllerFactory; public ControllerActionInvoker(RequestContext requestContext, - ControllerBasedActionDescriptor descriptor, + ControllerActionRouteContext descriptor, IActionResultFactory actionResultFactory, IControllerFactory controllerFactory, IServiceProvider serviceProvider) @@ -31,26 +29,31 @@ namespace Microsoft.AspNet.Mvc public Task InvokeActionAsync() { + IActionResult actionResult = null; + object controller = _controllerFactory.CreateController(_requestContext.HttpContext, _descriptor.ControllerName); if (controller == null) { - throw new InvalidOperationException(String.Format("Couldn't find controller '{0}'.", _descriptor.ControllerName)); + actionResult = new HttpStatusCodeResult(404); } - - Initialize(controller); - - var method = controller.GetType().GetRuntimeMethods().FirstOrDefault(m => m.Name.Equals(_descriptor.ActionName, StringComparison.OrdinalIgnoreCase)); - - if (method == null) + else { - throw new InvalidOperationException(String.Format("Could not find action method '{0}'", _descriptor.ActionName)); + Initialize(controller); + + var method = controller.GetType().GetRuntimeMethods().FirstOrDefault(m => m.Name.Equals(_descriptor.ActionName, StringComparison.OrdinalIgnoreCase)); + + if (method == null) + { + throw new InvalidOperationException(String.Format("Could not find action method '{0}'", _descriptor.ActionName)); + } + + object actionReturnValue = method.Invoke(controller, null); + + actionResult = _actionResultFactory.CreateActionResult(method.ReturnType, actionReturnValue, _requestContext); } - object actionReturnValue = method.Invoke(controller, null); - - var actionResult = _actionResultFactory.CreateActionResult(method.ReturnType, actionReturnValue, _requestContext); - + // TODO: This will probably move out once we got filters return actionResult.ExecuteResultAsync(_requestContext); } diff --git a/src/Microsoft.AspNet.Mvc/ControllerBasedActionDescriptor.cs b/src/Microsoft.AspNet.Mvc/ControllerBasedActionDescriptor.cs index 71baa1dd20..378ce8dda6 100644 --- a/src/Microsoft.AspNet.Mvc/ControllerBasedActionDescriptor.cs +++ b/src/Microsoft.AspNet.Mvc/ControllerBasedActionDescriptor.cs @@ -1,7 +1,6 @@ - -namespace Microsoft.AspNet.Mvc +namespace Microsoft.AspNet.Mvc { - public class ControllerBasedActionDescriptor : ActionDescriptor + public class ControllerActionRouteContext : RouteContext { public string ControllerName { get; set; } diff --git a/src/Microsoft.AspNet.Mvc/ControllerCache.cs b/src/Microsoft.AspNet.Mvc/ControllerCache.cs index 1d6267a64e..a348f452a9 100644 --- a/src/Microsoft.AspNet.Mvc/ControllerCache.cs +++ b/src/Microsoft.AspNet.Mvc/ControllerCache.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; - namespace Microsoft.AspNet.Mvc { public abstract class ControllerCache diff --git a/src/Microsoft.AspNet.Mvc/DefaultControllerCache.cs b/src/Microsoft.AspNet.Mvc/DefaultControllerCache.cs index 3a54073b51..df01542db5 100644 --- a/src/Microsoft.AspNet.Mvc/DefaultControllerCache.cs +++ b/src/Microsoft.AspNet.Mvc/DefaultControllerCache.cs @@ -28,7 +28,14 @@ namespace Microsoft.AspNet.Mvc throw new InvalidOperationException("Finalizing the setup must happen prior to accessing controllers"); } - return Controllers[controllerName]; + IEnumerable descriptors = null; + + if (Controllers.TryGetValue(controllerName, out descriptors)) + { + return descriptors; + } + + return null; } public Dictionary> ScanAppDomain() diff --git a/src/Microsoft.AspNet.Mvc/DefaultControllerFactory.cs b/src/Microsoft.AspNet.Mvc/DefaultControllerFactory.cs index 38782c76a7..16a248a63e 100644 --- a/src/Microsoft.AspNet.Mvc/DefaultControllerFactory.cs +++ b/src/Microsoft.AspNet.Mvc/DefaultControllerFactory.cs @@ -26,12 +26,12 @@ namespace Microsoft.AspNet.Mvc var controllers = _controllerCache.GetController(controllerName); - try + if (controllers != null) { - var type = controllers.SingleOrDefault().ControllerType; - - if (type != null) + try { + var type = controllers.Single().ControllerType; + try { return ActivatorUtilities.CreateInstance(_serviceProvider, type); @@ -40,10 +40,10 @@ namespace Microsoft.AspNet.Mvc { } } - } - catch (InvalidOperationException) - { - throw new InvalidOperationException("Ambiguity: Duplicate controllers match the controller name"); + catch (InvalidOperationException) + { + throw new InvalidOperationException("Ambiguity: Duplicate controllers match the controller name"); + } } return null; diff --git a/src/Microsoft.AspNet.Mvc/IActionDescriptorProvider.cs b/src/Microsoft.AspNet.Mvc/IActionDescriptorProvider.cs index 0eab785a57..70d8b4565d 100644 --- a/src/Microsoft.AspNet.Mvc/IActionDescriptorProvider.cs +++ b/src/Microsoft.AspNet.Mvc/IActionDescriptorProvider.cs @@ -2,8 +2,8 @@ namespace Microsoft.AspNet.Mvc { - public interface IActionDescriptorProvider + public interface IRouteContextProvider { - ActionDescriptor CreateDescriptor(RequestContext requestContext); + RouteContext CreateDescriptor(RequestContext requestContext); } } diff --git a/src/Microsoft.AspNet.Mvc/IActionInvokerProvider.cs b/src/Microsoft.AspNet.Mvc/IActionInvokerProvider.cs index 99abbd3d8f..c2528819dd 100644 --- a/src/Microsoft.AspNet.Mvc/IActionInvokerProvider.cs +++ b/src/Microsoft.AspNet.Mvc/IActionInvokerProvider.cs @@ -3,6 +3,6 @@ namespace Microsoft.AspNet.Mvc { public interface IActionInvokerProvider { - IActionInvoker GetInvoker(RequestContext requestContext, ActionDescriptor descriptor); + IActionInvoker GetInvoker(RequestContext requestContext, RouteContext routeContext); } } diff --git a/src/Microsoft.AspNet.Mvc/RouteContext.cs b/src/Microsoft.AspNet.Mvc/RouteContext.cs new file mode 100644 index 0000000000..1fe48b6f6e --- /dev/null +++ b/src/Microsoft.AspNet.Mvc/RouteContext.cs @@ -0,0 +1,6 @@ +namespace Microsoft.AspNet.Mvc +{ + public class RouteContext + { + } +}