diff --git a/src/Umbraco.Web/Mvc/IRenderMvcController.cs b/src/Umbraco.Web/Mvc/IRenderMvcController.cs new file mode 100644 index 0000000000..de4dc1045a --- /dev/null +++ b/src/Umbraco.Web/Mvc/IRenderMvcController.cs @@ -0,0 +1,18 @@ +using System.Web.Mvc; +using Umbraco.Web.Models; + +namespace Umbraco.Web.Mvc +{ + /// + /// The interface that must be implemented for a controller to be designated to execute for route hijacking + /// + public interface IRenderMvcController : IController + { + /// + /// The default action to render the front-end view + /// + /// + /// + ActionResult Index(RenderModel model); + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Mvc/RenderActionInvoker.cs b/src/Umbraco.Web/Mvc/RenderActionInvoker.cs index 014b0c1e48..4fa9702a61 100644 --- a/src/Umbraco.Web/Mvc/RenderActionInvoker.cs +++ b/src/Umbraco.Web/Mvc/RenderActionInvoker.cs @@ -22,8 +22,8 @@ namespace Umbraco.Web.Mvc //now we need to check if it exists, if not we need to return the Index by default if (ad == null) { - //check if the controller is an instance of RenderMvcController - if (controllerContext.Controller is RenderMvcController) + //check if the controller is an instance of IRenderMvcController + if (controllerContext.Controller is IRenderMvcController) { return new ReflectedActionDescriptor(controllerContext.Controller.GetType().GetMethod("Index"), "Index", controllerDescriptor); } diff --git a/src/Umbraco.Web/Mvc/RenderControllerFactory.cs b/src/Umbraco.Web/Mvc/RenderControllerFactory.cs index 56270ea36e..c1ee52ed0a 100644 --- a/src/Umbraco.Web/Mvc/RenderControllerFactory.cs +++ b/src/Umbraco.Web/Mvc/RenderControllerFactory.cs @@ -54,12 +54,24 @@ namespace Umbraco.Web.Mvc /// The controller. /// /// The request context.The name of the controller. + /// + /// We always set the correct ActionInvoker on our custom created controller, this is very important for route hijacking! + /// public virtual IController CreateController(RequestContext requestContext, string controllerName) { Type controllerType = GetControllerType(requestContext, controllerName) ?? _innerFactory.GetControllerType(requestContext, ControllerExtensions.GetControllerName(typeof(RenderMvcController))); - return _innerFactory.GetControllerInstance(requestContext, controllerType); + var instance = _innerFactory.GetControllerInstance(requestContext, controllerType); + + var controllerInstance = instance as Controller; + if (controllerInstance != null) + { + //set the action invoker! + controllerInstance.ActionInvoker = new RenderActionInvoker(); + } + + return instance; } /// diff --git a/src/Umbraco.Web/Mvc/RenderMvcController.cs b/src/Umbraco.Web/Mvc/RenderMvcController.cs index 92e2715a0b..6bc1fbcdfa 100644 --- a/src/Umbraco.Web/Mvc/RenderMvcController.cs +++ b/src/Umbraco.Web/Mvc/RenderMvcController.cs @@ -11,8 +11,11 @@ using Umbraco.Web.Routing; namespace Umbraco.Web.Mvc { - public class RenderMvcController : Controller - { + /// + /// The default controller that is executed for rendering MVC content in Umbraco + /// + public class RenderMvcController : Controller, IRenderMvcController + { public RenderMvcController() { diff --git a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs index f8e2622ee6..900ca00c43 100644 --- a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs @@ -239,11 +239,11 @@ namespace Umbraco.Web.Mvc if (controller != null) { - //ensure the controller is of type 'RenderMvcController' - if (controller is RenderMvcController) + //ensure the controller is of type 'IRenderMvcController' and ControllerBase + if (controller is IRenderMvcController && controller is ControllerBase) { //set the controller and name to the custom one - def.Controller = (ControllerBase)controller; + def.Controller = (ControllerBase)controller; def.ControllerName = ControllerExtensions.GetControllerName(controller.GetType()); if (def.ControllerName != defaultControllerName) { @@ -253,10 +253,11 @@ namespace Umbraco.Web.Mvc else { LogHelper.Warn( - "The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must inherit from '{2}'.", + "The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must implement '{2}' and inherit from '{3}'.", () => publishedContentRequest.PublishedContent.DocumentTypeAlias, () => controller.GetType().FullName, - () => typeof(RenderMvcController).FullName); + () => typeof(IRenderMvcController).FullName, + () => typeof(ControllerBase).FullName); //exit as we cannnot route to the custom controller, just route to the standard one. return def; } diff --git a/src/Umbraco.Web/Mvc/SurfaceControllerFactory.cs b/src/Umbraco.Web/Mvc/SurfaceControllerFactory.cs index a6eeda68d6..39a9e987ac 100644 --- a/src/Umbraco.Web/Mvc/SurfaceControllerFactory.cs +++ b/src/Umbraco.Web/Mvc/SurfaceControllerFactory.cs @@ -4,6 +4,8 @@ using System.Web.Routing; namespace Umbraco.Web.Mvc { + //NOTE: We currently are not using this at all and should/could probably remove it! + /// /// Creates SurfaceControllers /// diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index bf55cc31d4..686ece02d1 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -279,6 +279,7 @@ +