Merge
This commit is contained in:
@@ -26,7 +26,7 @@ namespace Umbraco.Web.Mvc
|
||||
/// <param name="umbracoTokenValue">The DataToken value to set for the 'umbraco' key, this defaults to 'backoffice' </param>
|
||||
/// <remarks>
|
||||
/// </remarks>
|
||||
internal static void RouteControllerPlugin(this AreaRegistration area, string controllerName, Type controllerType, RouteCollection routes,
|
||||
internal static Route RouteControllerPlugin(this AreaRegistration area, string controllerName, Type controllerType, RouteCollection routes,
|
||||
string controllerSuffixName, string defaultAction, object defaultId,
|
||||
string umbracoTokenValue = "backoffice")
|
||||
{
|
||||
@@ -72,6 +72,7 @@ namespace Umbraco.Web.Mvc
|
||||
controllerPluginRoute.DataTokens.Add("area", area.AreaName);
|
||||
controllerPluginRoute.DataTokens.Add("umbraco", umbracoTokenValue); //ensure the umbraco token is set
|
||||
|
||||
return controllerPluginRoute;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
|
||||
public interface IFilteredControllerFactory : IControllerFactory
|
||||
{
|
||||
/// <summary>
|
||||
@@ -13,5 +15,6 @@ namespace Umbraco.Web.Mvc
|
||||
/// <returns><c>true</c> if this instance can handle the specified request; otherwise, <c>false</c>.</returns>
|
||||
/// <remarks></remarks>
|
||||
bool CanHandle(RequestContext request);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,37 @@ namespace Umbraco.Web.Mvc
|
||||
: base.CreateController(requestContext, controllerName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the controller type for the specified name and request context.
|
||||
/// </summary>
|
||||
///
|
||||
/// <returns>
|
||||
/// The controller type.
|
||||
/// </returns>
|
||||
/// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
|
||||
/// <param name="controllerName">The name of the controller.</param>
|
||||
internal Type GetControllerTypeInternal(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
var factory = _slaveFactories.Factories.FirstOrDefault(x => x.CanHandle(requestContext));
|
||||
if (factory != null)
|
||||
{
|
||||
//check to see if the factory is of type UmbracoControllerFactory which exposes the GetControllerType method so we don't have to create
|
||||
// an instance of the controller to figure out what it is. This is a work around for not having a breaking change for:
|
||||
// http://issues.umbraco.org/issue/U4-1726
|
||||
|
||||
var umbFactory = factory as UmbracoControllerFactory;
|
||||
if (umbFactory != null)
|
||||
{
|
||||
return umbFactory.GetControllerType(requestContext, controllerName);
|
||||
}
|
||||
//we have no choice but to instantiate the controller
|
||||
var instance = factory.CreateController(requestContext, controllerName);
|
||||
return instance.GetType();
|
||||
}
|
||||
|
||||
return base.GetControllerType(requestContext, controllerName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the specified controller.
|
||||
/// </summary>
|
||||
|
||||
@@ -67,7 +67,9 @@ namespace Umbraco.Web.Mvc
|
||||
{
|
||||
foreach (var s in surfaceControllers)
|
||||
{
|
||||
this.RouteControllerPlugin(s.ControllerName, s.ControllerType, routes, "Surface", "Index", UrlParameter.Optional, "surface");
|
||||
var route = this.RouteControllerPlugin(s.ControllerName, s.ControllerType, routes, "Surface", "Index", UrlParameter.Optional, "surface");
|
||||
//set the route handler to our SurfaceRouteHandler
|
||||
route.RouteHandler = new SurfaceRouteHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,109 +1,26 @@
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using System.Web.SessionState;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// A controller factory for the render pipeline of Umbraco. This controller factory tries to create a controller with the supplied
|
||||
/// name, and falls back to UmbracoController if none was found.
|
||||
/// </summary>
|
||||
/// <remarks></remarks>
|
||||
public class RenderControllerFactory : IFilteredControllerFactory
|
||||
public class RenderControllerFactory : UmbracoControllerFactory
|
||||
{
|
||||
private readonly OverridenDefaultControllerFactory _innerFactory = new OverridenDefaultControllerFactory();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:System.Object"/> class.
|
||||
/// </summary>
|
||||
public RenderControllerFactory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this instance can handle the specified request.
|
||||
/// </summary>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <returns><c>true</c> if this instance can handle the specified request; otherwise, <c>false</c>.</returns>
|
||||
/// <remarks></remarks>
|
||||
public virtual bool CanHandle(RequestContext request)
|
||||
public override bool CanHandle(RequestContext request)
|
||||
{
|
||||
var dataToken = request.RouteData.DataTokens["area"];
|
||||
return dataToken == null || string.IsNullOrWhiteSpace(dataToken.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the controller type for the controller name otherwise null if not found
|
||||
/// </summary>
|
||||
/// <param name="requestContext"></param>
|
||||
/// <param name="controllerName"></param>
|
||||
/// <returns></returns>
|
||||
protected Type GetControllerType(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
return _innerFactory.GetControllerType(requestContext, controllerName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the specified controller by using the specified request context.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The controller.
|
||||
/// </returns>
|
||||
/// <param name="requestContext">The request context.</param><param name="controllerName">The name of the controller.</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the controller's session behavior.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The controller's session behavior.
|
||||
/// </returns>
|
||||
/// <param name="requestContext">The request context.</param><param name="controllerName">The name of the controller whose session behavior you want to get.</param>
|
||||
public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
return ((IControllerFactory)_innerFactory).GetControllerSessionBehavior(requestContext, controllerName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the specified controller.
|
||||
/// </summary>
|
||||
/// <param name="controller">The controller.</param>
|
||||
public void ReleaseController(IController controller)
|
||||
{
|
||||
_innerFactory.ReleaseController(controller);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// By default, <see cref="DefaultControllerFactory"/> only exposes <see cref="IControllerFactory.CreateController"/> which throws an exception
|
||||
/// if the controller is not found. Since we want to try creating a controller, and then fall back to <see cref="RenderMvcController"/> if one isn't found,
|
||||
/// this nested class changes the visibility of <see cref="DefaultControllerFactory"/>'s internal methods in order to not have to rely on a try-catch.
|
||||
/// </summary>
|
||||
/// <remarks></remarks>
|
||||
internal class OverridenDefaultControllerFactory : DefaultControllerFactory
|
||||
{
|
||||
public new IController GetControllerInstance(RequestContext requestContext, Type controllerType)
|
||||
{
|
||||
return base.GetControllerInstance(requestContext, controllerType);
|
||||
}
|
||||
|
||||
public new Type GetControllerType(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
if (controllerName.IsNullOrWhiteSpace())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return base.GetControllerType(requestContext, controllerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using System.Web.SessionState;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Configuration;
|
||||
@@ -181,35 +182,46 @@ namespace Umbraco.Web.Mvc
|
||||
requestContext.RouteData.Values["controller"] = postedInfo.ControllerName;
|
||||
requestContext.RouteData.Values["action"] = postedInfo.ActionName;
|
||||
|
||||
IHttpHandler handler = new MvcHandler(requestContext);
|
||||
|
||||
//ensure the controllerType is set if found, meaning it is a plugin, not locally declared
|
||||
IHttpHandler handler;
|
||||
|
||||
//get the route from the defined routes
|
||||
if (!postedInfo.Area.IsNullOrWhiteSpace())
|
||||
{
|
||||
//requestContext.RouteData.Values["controllerType"] = postedInfo.ControllerType;
|
||||
//find the other data tokens for this route and merge... things like Namespace will be included here
|
||||
using (RouteTable.Routes.GetReadLock())
|
||||
{
|
||||
var surfaceRoute = RouteTable.Routes.OfType<Route>()
|
||||
.SingleOrDefault(x => x.Defaults != null &&
|
||||
x.Defaults.ContainsKey("controller") &&
|
||||
using (RouteTable.Routes.GetReadLock())
|
||||
{
|
||||
Route surfaceRoute;
|
||||
if (postedInfo.Area == standardArea)
|
||||
{
|
||||
//find the controller in the route table without an area
|
||||
surfaceRoute = RouteTable.Routes.OfType<Route>()
|
||||
.SingleOrDefault(x => x.Defaults != null &&
|
||||
x.Defaults.ContainsKey("controller") &&
|
||||
x.Defaults["controller"].ToString() == postedInfo.ControllerName &&
|
||||
!x.DataTokens.ContainsKey("area"));
|
||||
}
|
||||
else
|
||||
{
|
||||
//find the controller in the route table with the specified area
|
||||
surfaceRoute = RouteTable.Routes.OfType<Route>()
|
||||
.SingleOrDefault(x => x.Defaults != null &&
|
||||
x.Defaults.ContainsKey("controller") &&
|
||||
x.Defaults["controller"].ToString().InvariantEquals(postedInfo.ControllerName) &&
|
||||
x.DataTokens.ContainsKey("area") &&
|
||||
x.DataTokens.ContainsKey("area") &&
|
||||
x.DataTokens["area"].ToString().InvariantEquals(postedInfo.Area));
|
||||
if (surfaceRoute == null)
|
||||
throw new InvalidOperationException("Could not find a Surface controller route in the RouteTable for controller name " + postedInfo.ControllerName + " and within the area of " + postedInfo.Area);
|
||||
}
|
||||
|
||||
if (surfaceRoute == null)
|
||||
throw new InvalidOperationException("Could not find a Surface controller route in the RouteTable for controller name " + postedInfo.ControllerName);
|
||||
|
||||
requestContext.RouteData.DataTokens["area"] = surfaceRoute.DataTokens["area"];
|
||||
|
||||
//set the 'Namespaces' token so the controller factory knows where to look to construct it
|
||||
if (surfaceRoute.DataTokens.ContainsKey("Namespaces"))
|
||||
{
|
||||
requestContext.RouteData.DataTokens["Namespaces"] = surfaceRoute.DataTokens["Namespaces"];
|
||||
}
|
||||
handler = surfaceRoute.RouteHandler.GetHttpHandler(requestContext);
|
||||
}
|
||||
//set the 'Namespaces' token so the controller factory knows where to look to construct it
|
||||
if (surfaceRoute.DataTokens.ContainsKey("Namespaces"))
|
||||
{
|
||||
requestContext.RouteData.DataTokens["Namespaces"] = surfaceRoute.DataTokens["Namespaces"];
|
||||
}
|
||||
handler = surfaceRoute.RouteHandler.GetHttpHandler(requestContext);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//store the original route definition
|
||||
requestContext.RouteData.DataTokens["umbraco-route-def"] = routeDefinition;
|
||||
@@ -230,57 +242,53 @@ namespace Umbraco.Web.Mvc
|
||||
var def = new RouteDefinition
|
||||
{
|
||||
ControllerName = defaultControllerName,
|
||||
Controller = new RenderMvcController(UmbracoContext),
|
||||
ControllerType = typeof(RenderMvcController),
|
||||
PublishedContentRequest = publishedContentRequest,
|
||||
ActionName = ((Route)requestContext.RouteData.Route).Defaults["action"].ToString(),
|
||||
HasHijackedRoute = false
|
||||
};
|
||||
|
||||
//check that a template is defined), if it doesn't and there is a hijacked route it will just route
|
||||
// to the index Action
|
||||
if (publishedContentRequest.HasTemplate)
|
||||
{
|
||||
//the template Alias should always be already saved with a safe name.
|
||||
//if there are hyphens in the name and there is a hijacked route, then the Action will need to be attributed
|
||||
// with the action name attribute.
|
||||
var templateName = publishedContentRequest.TemplateAlias.Split('.')[0].ToSafeAlias();
|
||||
def.ActionName = templateName;
|
||||
}
|
||||
|
||||
//check if there's a custom controller assigned, base on the document type alias.
|
||||
var controller = _controllerFactory.CreateController(requestContext, publishedContentRequest.PublishedContent.DocumentTypeAlias);
|
||||
|
||||
|
||||
var controllerType = ((MasterControllerFactory)_controllerFactory).GetControllerTypeInternal(requestContext, publishedContentRequest.PublishedContent.DocumentTypeAlias);
|
||||
|
||||
//check if that controller exists
|
||||
if (controller != null)
|
||||
{
|
||||
if (controllerType != null)
|
||||
{
|
||||
//ensure the controller is of type 'RenderMvcController'
|
||||
if (controllerType.IsSubclassOf(typeof (RenderMvcController)))
|
||||
{
|
||||
//set the controller and name to the custom one
|
||||
def.ControllerType = controllerType;
|
||||
def.ControllerName = ControllerExtensions.GetControllerName(controllerType);
|
||||
if (def.ControllerName != defaultControllerName)
|
||||
{
|
||||
def.HasHijackedRoute = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Warn<RenderRouteHandler>(
|
||||
"The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must inherit from '{2}'.",
|
||||
() => publishedContentRequest.PublishedContent.DocumentTypeAlias,
|
||||
() => controllerType.FullName,
|
||||
() => typeof (RenderMvcController).FullName);
|
||||
//exit as we cannnot route to the custom controller, just route to the standard one.
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
//ensure the controller is of type 'RenderMvcController'
|
||||
if (controller is RenderMvcController)
|
||||
{
|
||||
//set the controller and name to the custom one
|
||||
def.Controller = (ControllerBase)controller;
|
||||
def.ControllerName = ControllerExtensions.GetControllerName(controller.GetType());
|
||||
if (def.ControllerName != defaultControllerName)
|
||||
{
|
||||
def.HasHijackedRoute = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Warn<RenderRouteHandler>(
|
||||
"The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must inherit from '{2}'.",
|
||||
() => publishedContentRequest.PublishedContent.DocumentTypeAlias,
|
||||
() => controller.GetType().FullName,
|
||||
() => typeof(RenderMvcController).FullName);
|
||||
//exit as we cannnot route to the custom controller, just route to the standard one.
|
||||
return def;
|
||||
}
|
||||
|
||||
//check that a template is defined), if it doesn't and there is a hijacked route it will just route
|
||||
// to the index Action
|
||||
if (publishedContentRequest.HasTemplate)
|
||||
{
|
||||
//the template Alias should always be already saved with a safe name.
|
||||
//if there are hyphens in the name and there is a hijacked route, then the Action will need to be attributed
|
||||
// with the action name attribute.
|
||||
var templateName = publishedContentRequest.TemplateAlias.Split('.')[0].ToSafeAlias();
|
||||
def.ActionName = templateName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return def;
|
||||
return def;
|
||||
}
|
||||
|
||||
internal IHttpHandler GetHandlerOnMissingTemplate(PublishedContentRequest pcr)
|
||||
@@ -363,11 +371,19 @@ namespace Umbraco.Web.Mvc
|
||||
requestContext.RouteData.Values["action"] = routeDef.ActionName;
|
||||
}
|
||||
|
||||
// Set the session state requirements
|
||||
requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext, routeDef.ControllerName));
|
||||
|
||||
// reset the friendly path so in the controllers and anything occuring after this point in time,
|
||||
//the URL is reset back to the original request.
|
||||
requestContext.HttpContext.RewritePath(UmbracoContext.OriginalRequestUrl.PathAndQuery);
|
||||
|
||||
return new MvcHandler(requestContext);
|
||||
return new UmbracoMvcHandler(requestContext);
|
||||
}
|
||||
|
||||
private SessionStateBehavior GetSessionStateBehavior(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
return _controllerFactory.GetControllerSessionBehavior(requestContext, controllerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
@@ -16,6 +17,12 @@ namespace Umbraco.Web.Mvc
|
||||
/// </summary>
|
||||
public ControllerBase Controller { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Controller type found for routing to
|
||||
/// </summary>
|
||||
public Type ControllerType { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The current RenderModel found for the request
|
||||
/// </summary>
|
||||
|
||||
16
src/Umbraco.Web/Mvc/SurfaceRouteHandler.cs
Normal file
16
src/Umbraco.Web/Mvc/SurfaceRouteHandler.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Web;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Assigned to all SurfaceController's so that it returns our custom SurfaceMvcHandler to use for rendering
|
||||
/// </summary>
|
||||
internal class SurfaceRouteHandler : IRouteHandler
|
||||
{
|
||||
public IHttpHandler GetHttpHandler(RequestContext requestContext)
|
||||
{
|
||||
return new UmbracoMvcHandler(requestContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/Umbraco.Web/Mvc/UmbracoControllerFactory.cs
Normal file
82
src/Umbraco.Web/Mvc/UmbracoControllerFactory.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using System.Web.SessionState;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract filtered controller factory used for all Umbraco controller factory implementations
|
||||
/// </summary>
|
||||
public abstract class UmbracoControllerFactory : IFilteredControllerFactory
|
||||
{
|
||||
private readonly OverridenDefaultControllerFactory _innerFactory = new OverridenDefaultControllerFactory();
|
||||
|
||||
public abstract bool CanHandle(RequestContext request);
|
||||
|
||||
public virtual Type GetControllerType(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
return _innerFactory.GetControllerType(requestContext, controllerName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the specified controller by using the specified request context.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The controller.
|
||||
/// </returns>
|
||||
/// <param name="requestContext">The request context.</param><param name="controllerName">The name of the controller.</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the controller's session behavior.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The controller's session behavior.
|
||||
/// </returns>
|
||||
/// <param name="requestContext">The request context.</param><param name="controllerName">The name of the controller whose session behavior you want to get.</param>
|
||||
public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
return ((IControllerFactory)_innerFactory).GetControllerSessionBehavior(requestContext, controllerName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Releases the specified controller.
|
||||
/// </summary>
|
||||
/// <param name="controller">The controller.</param>
|
||||
public void ReleaseController(IController controller)
|
||||
{
|
||||
_innerFactory.ReleaseController(controller);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// By default, <see cref="DefaultControllerFactory"/> only exposes <see cref="IControllerFactory.CreateController"/> which throws an exception
|
||||
/// if the controller is not found. Since we want to try creating a controller, and then fall back to <see cref="RenderMvcController"/> if one isn't found,
|
||||
/// this nested class changes the visibility of <see cref="DefaultControllerFactory"/>'s internal methods in order to not have to rely on a try-catch.
|
||||
/// </summary>
|
||||
/// <remarks></remarks>
|
||||
internal class OverridenDefaultControllerFactory : DefaultControllerFactory
|
||||
{
|
||||
public new IController GetControllerInstance(RequestContext requestContext, Type controllerType)
|
||||
{
|
||||
return base.GetControllerInstance(requestContext, controllerType);
|
||||
}
|
||||
|
||||
public new Type GetControllerType(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
if (controllerName.IsNullOrWhiteSpace())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return base.GetControllerType(requestContext, controllerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
src/Umbraco.Web/Mvc/UmbracoMvcHandler.cs
Normal file
57
src/Umbraco.Web/Mvc/UmbracoMvcHandler.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace Umbraco.Web.Mvc
|
||||
{
|
||||
/// <summary>
|
||||
/// Mvc handler class to intercept creation of controller and store it for later use.
|
||||
/// This means we create two instances of the same controller to support some features later on.
|
||||
///
|
||||
/// The alternate option for this is to completely rewrite all MvcHandler methods.
|
||||
///
|
||||
/// This is currently needed for the 'return CurrentUmbracoPage()' surface controller functionality
|
||||
/// because it needs to send data back to the page controller.
|
||||
/// </summary>
|
||||
internal class UmbracoMvcHandler : MvcHandler
|
||||
{
|
||||
public UmbracoMvcHandler(RequestContext requestContext)
|
||||
: base(requestContext)
|
||||
{
|
||||
}
|
||||
|
||||
private void StoreControllerInRouteDefinition()
|
||||
{
|
||||
var routeDef = (RouteDefinition)RequestContext.RouteData.DataTokens["umbraco-route-def"];
|
||||
|
||||
if (routeDef == null) return;
|
||||
|
||||
// Get the factory and controller and create a new instance of the controller
|
||||
var factory = ControllerBuilder.Current.GetControllerFactory();
|
||||
var controller = factory.CreateController(RequestContext, routeDef.ControllerName) as ControllerBase;
|
||||
|
||||
// Store the controller
|
||||
routeDef.Controller = controller;
|
||||
}
|
||||
|
||||
protected override void ProcessRequest(HttpContextBase httpContext)
|
||||
{
|
||||
StoreControllerInRouteDefinition();
|
||||
|
||||
// Let MVC do its magic and continue the request
|
||||
base.ProcessRequest(httpContext);
|
||||
}
|
||||
|
||||
protected override IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback,
|
||||
object state)
|
||||
{
|
||||
StoreControllerInRouteDefinition();
|
||||
|
||||
return base.BeginProcessRequest(httpContext, callback, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -300,9 +300,12 @@
|
||||
<Compile Include="DefaultPublishedMediaStore.cs" />
|
||||
<Compile Include="Dictionary\UmbracoCultureDictionary.cs" />
|
||||
<Compile Include="Dictionary\UmbracoCultureDictionaryFactory.cs" />
|
||||
<Compile Include="Mvc\SurfaceRouteHandler.cs" />
|
||||
<Compile Include="Mvc\UmbracoAuthorizeAttribute.cs" />
|
||||
<Compile Include="Mvc\UmbracoAuthorizedController.cs" />
|
||||
<Compile Include="Mvc\UmbracoController.cs" />
|
||||
<Compile Include="Mvc\UmbracoControllerFactory.cs" />
|
||||
<Compile Include="Mvc\UmbracoMvcHandler.cs" />
|
||||
<Compile Include="Mvc\UmbracoViewPage.cs" />
|
||||
<Compile Include="PublishedContentExtensions.cs" />
|
||||
<Compile Include="ExamineExtensions.cs" />
|
||||
|
||||
@@ -153,7 +153,9 @@ namespace Umbraco.Web
|
||||
umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}",//url to match
|
||||
new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional },
|
||||
new[] { meta.ControllerNamespace }); //only match this namespace
|
||||
route.DataTokens.Add("umbraco", "surface"); //ensure the umbraco token is set
|
||||
route.DataTokens.Add("umbraco", "surface"); //ensure the umbraco token is set
|
||||
//make it use our custom/special SurfaceMvcHandler
|
||||
route.RouteHandler = new SurfaceRouteHandler();
|
||||
}
|
||||
|
||||
//need to get the plugin controllers that are unique to each area (group by)
|
||||
|
||||
Reference in New Issue
Block a user