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.
This commit is contained in:
Yishai Galatzer 2014-02-08 09:33:13 -08:00
parent b6a0969c1c
commit a725e4c9b5
15 changed files with 65 additions and 60 deletions

View File

@ -19,7 +19,7 @@ namespace MvcSample.RandomNameSpace
public string Index() public string Index()
{ {
return "Hello World"; return "Hello World: my namespace is " + this.GetType().Namespace;
} }
public IActionResult Something() public IActionResult Something()

View File

@ -12,10 +12,10 @@ namespace Microsoft.AspNet.Mvc.Razor
"/Views/{1}/{0}.cshtml", "/Views/{1}/{0}.cshtml",
"/Views/Shared/{0}.cshtml", "/Views/Shared/{0}.cshtml",
}; };
private readonly IActionDescriptorProvider _actionDescriptorProvider; private readonly IRouteContextProvider _actionDescriptorProvider;
private readonly IVirtualPathViewFactory _virtualPathFactory; private readonly IVirtualPathViewFactory _virtualPathFactory;
public RazorViewEngine(IActionDescriptorProvider actionDescriptorProvider, public RazorViewEngine(IRouteContextProvider actionDescriptorProvider,
IVirtualPathViewFactory virtualPathFactory) IVirtualPathViewFactory virtualPathFactory)
{ {
_actionDescriptorProvider = actionDescriptorProvider; _actionDescriptorProvider = actionDescriptorProvider;
@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Mvc.Razor
public async Task<ViewEngineResult> FindView(RequestContext requestContext, string viewName) public async Task<ViewEngineResult> FindView(RequestContext requestContext, string viewName)
{ {
var actionDescriptor = _actionDescriptorProvider.CreateDescriptor(requestContext) as ControllerBasedActionDescriptor; var actionDescriptor = _actionDescriptorProvider.CreateDescriptor(requestContext) as ControllerActionRouteContext;
if (actionDescriptor == null) if (actionDescriptor == null)
{ {

View File

@ -21,12 +21,11 @@ namespace Microsoft.AspNet.Mvc.Startup
{ {
Services = new ServiceProvider(); Services = new ServiceProvider();
AddAndRegisterForFinalization<ControllerCache, DefaultControllerCache>();
AddAndRegisterForFinalization<IControllerFactory, DefaultControllerFactory>(); AddAndRegisterForFinalization<IControllerFactory, DefaultControllerFactory>();
AddAndRegisterForFinalization<IActionInvokerFactory, ActionInvokerFactory>(); AddAndRegisterForFinalization<IActionInvokerFactory, ActionInvokerFactory>();
AddAndRegisterForFinalization<IActionResultHelper, ActionResultHelper>(); AddAndRegisterForFinalization<IActionResultHelper, ActionResultHelper>();
AddAndRegisterForFinalization<IActionResultFactory, ActionResultFactory>(); AddAndRegisterForFinalization<IActionResultFactory, ActionResultFactory>();
AddAndRegisterForFinalization<IActionDescriptorProvider, ActionDescriptorProvider>(); AddAndRegisterForFinalization<IRouteContextProvider, ControllerActionBasedRouteContextProvider>();
AddAndRegisterForFinalization<IActionInvokerProvider, ActionInvokerProvider>(); AddAndRegisterForFinalization<IActionInvokerProvider, ActionInvokerProvider>();
// need singleton support here. // need singleton support here.

View File

@ -1,7 +0,0 @@

namespace Microsoft.AspNet.Mvc
{
public class ActionDescriptor
{
}
}

View File

@ -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 controllerName = requestContext.RouteData.GetRouteValue("controller");
string actionName = requestContext.RouteData.GetRouteValue("action"); string actionName = requestContext.RouteData.GetRouteValue("action");
return new ControllerBasedActionDescriptor return new ControllerActionRouteContext
{ {
ControllerName = controllerName, ControllerName = controllerName,
ActionName = actionName ActionName = actionName

View File

@ -6,23 +6,23 @@ namespace Microsoft.AspNet.Mvc
public class ActionInvokerFactory : IActionInvokerFactory public class ActionInvokerFactory : IActionInvokerFactory
{ {
private readonly IActionResultFactory _actionResultFactory; private readonly IActionResultFactory _actionResultFactory;
private readonly IActionDescriptorProvider _actionDescriptorProvider;
private readonly IActionInvokerProvider _actionInvokerProvider; private readonly IActionInvokerProvider _actionInvokerProvider;
private readonly IRouteContextProvider _routeContextProvider;
public ActionInvokerFactory(IActionResultFactory actionResultFactory, public ActionInvokerFactory(IActionResultFactory actionResultFactory,
IActionDescriptorProvider actionDescriptorProvider, IRouteContextProvider actionDescriptorProvider,
IActionInvokerProvider actionInvokerProvider) IActionInvokerProvider actionInvokerProvider)
{ {
_actionResultFactory = actionResultFactory; _actionResultFactory = actionResultFactory;
_actionDescriptorProvider = actionDescriptorProvider; _routeContextProvider = actionDescriptorProvider;
_actionInvokerProvider = actionInvokerProvider; _actionInvokerProvider = actionInvokerProvider;
} }
public IActionInvoker CreateInvoker(RequestContext requestContext) 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);
} }
} }
} }

View File

@ -7,20 +7,20 @@ namespace Microsoft.AspNet.Mvc
{ {
private readonly IActionResultFactory _actionResultFactory; private readonly IActionResultFactory _actionResultFactory;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly IControllerFactory _controrllerFactory; private readonly IControllerFactory _controllerFactory;
public ActionInvokerProvider(IActionResultFactory actionResultFactory, public ActionInvokerProvider(IActionResultFactory actionResultFactory,
IControllerFactory controllerFactory, IControllerFactory controllerFactory,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
{ {
_actionResultFactory = actionResultFactory; _actionResultFactory = actionResultFactory;
_controrllerFactory = controllerFactory; _controllerFactory = controllerFactory;
_serviceProvider = serviceProvider; _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) if (controllerActionDescriptor != null)
{ {
@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Mvc
requestContext, requestContext,
controllerActionDescriptor, controllerActionDescriptor,
_actionResultFactory, _actionResultFactory,
_controrllerFactory, _controllerFactory,
_serviceProvider); _serviceProvider);
} }

View File

@ -1,23 +1,21 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions; using Microsoft.AspNet.Abstractions;
using Microsoft.AspNet.DependencyInjection;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
public class ControllerActionInvoker : IActionInvoker public class ControllerActionInvoker : IActionInvoker
{ {
private readonly RequestContext _requestContext; private readonly RequestContext _requestContext;
private readonly ControllerBasedActionDescriptor _descriptor; private readonly ControllerActionRouteContext _descriptor;
private readonly IActionResultFactory _actionResultFactory; private readonly IActionResultFactory _actionResultFactory;
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly IControllerFactory _controllerFactory; private readonly IControllerFactory _controllerFactory;
public ControllerActionInvoker(RequestContext requestContext, public ControllerActionInvoker(RequestContext requestContext,
ControllerBasedActionDescriptor descriptor, ControllerActionRouteContext descriptor,
IActionResultFactory actionResultFactory, IActionResultFactory actionResultFactory,
IControllerFactory controllerFactory, IControllerFactory controllerFactory,
IServiceProvider serviceProvider) IServiceProvider serviceProvider)
@ -31,26 +29,31 @@ namespace Microsoft.AspNet.Mvc
public Task InvokeActionAsync() public Task InvokeActionAsync()
{ {
IActionResult actionResult = null;
object controller = _controllerFactory.CreateController(_requestContext.HttpContext, _descriptor.ControllerName); object controller = _controllerFactory.CreateController(_requestContext.HttpContext, _descriptor.ControllerName);
if (controller == null) if (controller == null)
{ {
throw new InvalidOperationException(String.Format("Couldn't find controller '{0}'.", _descriptor.ControllerName)); actionResult = new HttpStatusCodeResult(404);
} }
else
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)); 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); // TODO: This will probably move out once we got filters
var actionResult = _actionResultFactory.CreateActionResult(method.ReturnType, actionReturnValue, _requestContext);
return actionResult.ExecuteResultAsync(_requestContext); return actionResult.ExecuteResultAsync(_requestContext);
} }

View File

@ -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; } public string ControllerName { get; set; }

View File

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
public abstract class ControllerCache public abstract class ControllerCache

View File

@ -28,7 +28,14 @@ namespace Microsoft.AspNet.Mvc
throw new InvalidOperationException("Finalizing the setup must happen prior to accessing controllers"); throw new InvalidOperationException("Finalizing the setup must happen prior to accessing controllers");
} }
return Controllers[controllerName]; IEnumerable<ControllerDescriptor> descriptors = null;
if (Controllers.TryGetValue(controllerName, out descriptors))
{
return descriptors;
}
return null;
} }
public Dictionary<string, IEnumerable<ControllerDescriptor>> ScanAppDomain() public Dictionary<string, IEnumerable<ControllerDescriptor>> ScanAppDomain()

View File

@ -26,12 +26,12 @@ namespace Microsoft.AspNet.Mvc
var controllers = _controllerCache.GetController(controllerName); var controllers = _controllerCache.GetController(controllerName);
try if (controllers != null)
{ {
var type = controllers.SingleOrDefault().ControllerType; try
if (type != null)
{ {
var type = controllers.Single().ControllerType;
try try
{ {
return ActivatorUtilities.CreateInstance(_serviceProvider, type); return ActivatorUtilities.CreateInstance(_serviceProvider, type);
@ -40,10 +40,10 @@ namespace Microsoft.AspNet.Mvc
{ {
} }
} }
} catch (InvalidOperationException)
catch (InvalidOperationException) {
{ throw new InvalidOperationException("Ambiguity: Duplicate controllers match the controller name");
throw new InvalidOperationException("Ambiguity: Duplicate controllers match the controller name"); }
} }
return null; return null;

View File

@ -2,8 +2,8 @@
namespace Microsoft.AspNet.Mvc namespace Microsoft.AspNet.Mvc
{ {
public interface IActionDescriptorProvider public interface IRouteContextProvider
{ {
ActionDescriptor CreateDescriptor(RequestContext requestContext); RouteContext CreateDescriptor(RequestContext requestContext);
} }
} }

View File

@ -3,6 +3,6 @@ namespace Microsoft.AspNet.Mvc
{ {
public interface IActionInvokerProvider public interface IActionInvokerProvider
{ {
IActionInvoker GetInvoker(RequestContext requestContext, ActionDescriptor descriptor); IActionInvoker GetInvoker(RequestContext requestContext, RouteContext routeContext);
} }
} }

View File

@ -0,0 +1,6 @@
namespace Microsoft.AspNet.Mvc
{
public class RouteContext
{
}
}