Fixes: #U4-1760 - allows a developer to set the default RenderMvcController on startup.

This commit is contained in:
Shannon Deminick
2013-04-28 16:09:24 -10:00
parent 7ff50e2652
commit 577d77cfab
7 changed files with 109 additions and 6 deletions

View File

@@ -38,6 +38,8 @@ namespace Umbraco.Tests.Routing
protected override void FreezeResolution()
{
DefaultRenderMvcControllerResolver.Current = new DefaultRenderMvcControllerResolver(typeof(RenderMvcController));
SurfaceControllerResolver.Current = new SurfaceControllerResolver(
PluginManager.Current.ResolveSurfaceControllers());
UmbracoApiControllerResolver.Current = new UmbracoApiControllerResolver(

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.ObjectResolution;
namespace Umbraco.Web.Mvc
{
/// <summary>
/// A resolver used to resolve the default RenderMvcController that is used to render any front-end
/// Umbraco page when using MVC when there are no routes hijacked.
/// </summary>
public class DefaultRenderMvcControllerResolver : SingleObjectResolverBase<DefaultRenderMvcControllerResolver, Type>
{
/// <summary>
/// Constructor accepting the default RenderMvcController
/// </summary>
/// <param name="value"></param>
public DefaultRenderMvcControllerResolver(Type value)
: base(value)
{
ValidateType(value);
}
/// <summary>
/// Returns the Default RenderMvcController type
/// </summary>
/// <returns></returns>
public Type GetDefaultControllerType()
{
return Value;
}
/// <summary>
/// Returns an instance of the default controller instance.
/// </summary>
public RenderMvcController GetControllerInstance()
{
//try the dependency resolver, then the activator
var instance = DependencyResolver.Current.GetService(Value) ?? Activator.CreateInstance(Value);
var result = instance as RenderMvcController;
if (result == null)
{
throw new InvalidOperationException("Could not create an instance of " + Value + " for the default RenderMvcController");
}
return result;
}
/// <summary>
/// Sets the default RenderMvcController type
/// </summary>
/// <param name="controllerType"></param>
public void SetDefaultControllerType(Type controllerType)
{
ValidateType(controllerType);
Value = controllerType;
}
/// <summary>
/// Ensures that the type passed in is of type RenderMvcController
/// </summary>
/// <param name="type"></param>
private void ValidateType(Type type)
{
if (TypeHelper.IsTypeAssignableFrom<RenderMvcController>(type) == false)
{
throw new InvalidOperationException("The Type specified (" + type + ") is not of type " + typeof(RenderMvcController));
}
}
}
}

View File

@@ -236,12 +236,13 @@ namespace Umbraco.Web.Mvc
/// <returns></returns>
internal virtual RouteDefinition GetUmbracoRouteDefinition(RequestContext requestContext, PublishedContentRequest publishedContentRequest)
{
var defaultControllerName = ControllerExtensions.GetControllerName<RenderMvcController>();
var defaultControllerType = DefaultRenderMvcControllerResolver.Current.GetDefaultControllerType();
var defaultControllerName = ControllerExtensions.GetControllerName(defaultControllerType);
//creates the default route definition which maps to the 'UmbracoController' controller
var def = new RouteDefinition
{
ControllerName = defaultControllerName,
ControllerType = typeof(RenderMvcController),
ControllerType = defaultControllerType,
PublishedContentRequest = publishedContentRequest,
ActionName = ((Route)requestContext.RouteData.Route).Defaults["action"].ToString(),
HasHijackedRoute = false
@@ -260,12 +261,12 @@ namespace Umbraco.Web.Mvc
//check if there's a custom controller assigned, base on the document type alias.
var controllerType = _controllerFactory.GetControllerTypeInternal(requestContext, publishedContentRequest.PublishedContent.DocumentTypeAlias);
//check if that controller exists
if (controllerType != null)
{
//ensure the controller is of type 'RenderMvcController'
if (controllerType.IsSubclassOf(typeof (RenderMvcController)))
if (TypeHelper.IsTypeAssignableFrom<RenderMvcController>(controllerType))
{
//set the controller and name to the custom one
def.ControllerType = controllerType;

View File

@@ -29,8 +29,11 @@ namespace Umbraco.Web.Mvc
/// <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)));
var controllerType = GetControllerType(requestContext, controllerName) ??
_innerFactory.GetControllerType(
requestContext,
ControllerExtensions.GetControllerName(
DefaultRenderMvcControllerResolver.Current.GetDefaultControllerType()));
return _innerFactory.GetControllerInstance(requestContext, controllerType);
}

View File

@@ -330,6 +330,7 @@
<Compile Include="BaseRest\RestExtensionMethodAttribute.cs" />
<Compile Include="BaseRest\RestExtensionMethodInfo.cs" />
<Compile Include="ContextualPublishedCacheExtensions.cs" />
<Compile Include="Mvc\DefaultRenderMvcControllerResolver.cs" />
<Compile Include="PublishedCache\ContextualPublishedContentCache.cs" />
<Compile Include="PublishedCache\ContextualPublishedCacheOfT.cs" />
<Compile Include="PublishedCache\ContextualPublishedCache.cs" />

View File

@@ -8,11 +8,30 @@ using System.Web.Hosting;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Web.Mvc;
using Umbraco.Web.Routing;
using umbraco.businesslogic;
namespace Umbraco.Web
{
public class CustomRenderController : RenderMvcController
{
public override ActionResult Index(Models.RenderModel model)
{
HttpContext.Response.ContentType = "text/plain";
return base.Index(model);
}
}
public class CustomApplicationEventHandler : ApplicationEventHandler
{
protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
DefaultRenderMvcControllerResolver.Current.SetDefaultControllerType(typeof(CustomRenderController));
base.ApplicationStarting(umbracoApplication, applicationContext);
}
}
/// <summary>
/// The Umbraco global.asax class
/// </summary>

View File

@@ -235,6 +235,9 @@ namespace Umbraco.Web
{
base.InitializeResolvers();
//set the default RenderMvcController
DefaultRenderMvcControllerResolver.Current = new DefaultRenderMvcControllerResolver(typeof(RenderMvcController));
//Override the ServerMessengerResolver to set a username/password for the distributed calls
ServerMessengerResolver.Current.SetServerMessenger(new DefaultServerMessenger(() =>
{