diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec
index 9578ef96d9..8ec1484452 100644
--- a/build/NuSpecs/UmbracoCms.nuspec
+++ b/build/NuSpecs/UmbracoCms.nuspec
@@ -25,7 +25,7 @@
not want this to happen as the alpha of the next major is, really, the next major already.
-->
-
+
diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs
index b7fd277ec7..f1f38504f1 100644
--- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs
+++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs
@@ -40,7 +40,7 @@ namespace Umbraco.Tests.Routing
{
base.SetUp();
- WebInitialComponent.CreateRoutes(
+ WebFinalComponent.CreateRoutes(
new TestUmbracoContextAccessor(),
TestObjects.GetGlobalSettings(),
new SurfaceControllerTypeCollection(Enumerable.Empty()),
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index 8cb9912890..8fb0dc6cd9 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -105,7 +105,7 @@
- 8.0.1
+ 8.0.4
diff --git a/src/Umbraco.Web/Runtime/WebFinalComponent.cs b/src/Umbraco.Web/Runtime/WebFinalComponent.cs
index 4673cc02e4..42ff0ee5e6 100644
--- a/src/Umbraco.Web/Runtime/WebFinalComponent.cs
+++ b/src/Umbraco.Web/Runtime/WebFinalComponent.cs
@@ -1,17 +1,130 @@
-using System.Web.Http;
+using System;
+using System.Linq;
+using System.Web.Http;
+using System.Web.Mvc;
+using System.Web.Routing;
+using Umbraco.Core;
using Umbraco.Core.Composing;
+using Umbraco.Core.Configuration;
+using Umbraco.Web.Install;
+using Umbraco.Web.Mvc;
+using Umbraco.Web.WebApi;
namespace Umbraco.Web.Runtime
{
public class WebFinalComponent : IComponent
{
+ private readonly IUmbracoContextAccessor _umbracoContextAccessor;
+ private readonly SurfaceControllerTypeCollection _surfaceControllerTypes;
+ private readonly UmbracoApiControllerTypeCollection _apiControllerTypes;
+ private readonly IGlobalSettings _globalSettings;
+
+ public WebFinalComponent(IUmbracoContextAccessor umbracoContextAccessor, SurfaceControllerTypeCollection surfaceControllerTypes, UmbracoApiControllerTypeCollection apiControllerTypes, IGlobalSettings globalSettings)
+ {
+ _umbracoContextAccessor = umbracoContextAccessor;
+ _surfaceControllerTypes = surfaceControllerTypes;
+ _apiControllerTypes = apiControllerTypes;
+ _globalSettings = globalSettings;
+ }
+
public void Initialize()
{
+ // set routes
+ CreateRoutes(_umbracoContextAccessor, _globalSettings, _surfaceControllerTypes, _apiControllerTypes);
+
// ensure WebAPI is initialized, after everything
GlobalConfiguration.Configuration.EnsureInitialized();
}
public void Terminate()
{ }
+
+ // internal for tests
+ internal static void CreateRoutes(
+ IUmbracoContextAccessor umbracoContextAccessor,
+ IGlobalSettings globalSettings,
+ SurfaceControllerTypeCollection surfaceControllerTypes,
+ UmbracoApiControllerTypeCollection apiControllerTypes)
+ {
+ var umbracoPath = globalSettings.GetUmbracoMvcArea();
+
+ // create the front-end route
+ var defaultRoute = RouteTable.Routes.MapRoute(
+ "Umbraco_default",
+ umbracoPath + "/RenderMvc/{action}/{id}",
+ new { controller = "RenderMvc", action = "Index", id = UrlParameter.Optional }
+ );
+ defaultRoute.RouteHandler = new RenderRouteHandler(umbracoContextAccessor, ControllerBuilder.Current.GetControllerFactory());
+
+ // register install routes
+ RouteTable.Routes.RegisterArea();
+
+ // register all back office routes
+ RouteTable.Routes.RegisterArea(new BackOfficeArea(globalSettings));
+
+ // plugin controllers must come first because the next route will catch many things
+ RoutePluginControllers(globalSettings, surfaceControllerTypes, apiControllerTypes);
+ }
+
+ private static void RoutePluginControllers(
+ IGlobalSettings globalSettings,
+ SurfaceControllerTypeCollection surfaceControllerTypes,
+ UmbracoApiControllerTypeCollection apiControllerTypes)
+ {
+ var umbracoPath = globalSettings.GetUmbracoMvcArea();
+
+ // need to find the plugin controllers and route them
+ var pluginControllers = surfaceControllerTypes.Concat(apiControllerTypes).ToArray();
+
+ // local controllers do not contain the attribute
+ var localControllers = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace());
+ foreach (var s in localControllers)
+ {
+ if (TypeHelper.IsTypeAssignableFrom(s))
+ RouteLocalSurfaceController(s, umbracoPath);
+ else if (TypeHelper.IsTypeAssignableFrom(s))
+ RouteLocalApiController(s, umbracoPath);
+ }
+
+ // get the plugin controllers that are unique to each area (group by)
+ var pluginSurfaceControlleres = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace() == false);
+ var groupedAreas = pluginSurfaceControlleres.GroupBy(controller => PluginController.GetMetadata(controller).AreaName);
+ // loop through each area defined amongst the controllers
+ foreach (var g in groupedAreas)
+ {
+ // create & register an area for the controllers (this will throw an exception if all controllers are not in the same area)
+ var pluginControllerArea = new PluginControllerArea(globalSettings, g.Select(PluginController.GetMetadata));
+ RouteTable.Routes.RegisterArea(pluginControllerArea);
+ }
+ }
+
+ private static void RouteLocalApiController(Type controller, string umbracoPath)
+ {
+ var meta = PluginController.GetMetadata(controller);
+ var url = umbracoPath + (meta.IsBackOffice ? "/BackOffice" : "") + "/Api/" + meta.ControllerName + "/{action}/{id}";
+ var route = RouteTable.Routes.MapHttpRoute(
+ $"umbraco-api-{meta.ControllerName}",
+ url, // url to match
+ new { controller = meta.ControllerName, id = UrlParameter.Optional },
+ new[] { meta.ControllerNamespace });
+ if (route.DataTokens == null) // web api routes don't set the data tokens object
+ route.DataTokens = new RouteValueDictionary();
+ route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "api"); //ensure the umbraco token is set
+ }
+
+ private static void RouteLocalSurfaceController(Type controller, string umbracoPath)
+ {
+ var meta = PluginController.GetMetadata(controller);
+ var url = umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}";
+ var route = RouteTable.Routes.MapRoute(
+ $"umbraco-surface-{meta.ControllerName}",
+ url, // url to match
+ new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional },
+ new[] { meta.ControllerNamespace }); // look in this namespace to create the controller
+ route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "surface"); // ensure the umbraco token is set
+ route.DataTokens.Add("UseNamespaceFallback", false); // don't look anywhere else except this namespace!
+ // make it use our custom/special SurfaceMvcHandler
+ route.RouteHandler = new SurfaceRouteHandler();
+ }
}
}
diff --git a/src/Umbraco.Web/Runtime/WebInitialComponent.cs b/src/Umbraco.Web/Runtime/WebInitialComponent.cs
index 3aaa8892eb..e1e0f4d80a 100644
--- a/src/Umbraco.Web/Runtime/WebInitialComponent.cs
+++ b/src/Umbraco.Web/Runtime/WebInitialComponent.cs
@@ -8,14 +8,12 @@ using System.Web.Configuration;
using System.Web.Http;
using System.Web.Http.Dispatcher;
using System.Web.Mvc;
-using System.Web.Routing;
using ClientDependency.Core.CompositeFiles.Providers;
using ClientDependency.Core.Config;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
-using Umbraco.Web.Install;
using Umbraco.Web.JavaScript;
using Umbraco.Web.Mvc;
using Umbraco.Web.WebApi;
@@ -26,20 +24,10 @@ namespace Umbraco.Web.Runtime
{
public sealed class WebInitialComponent : IComponent
{
- private readonly IUmbracoContextAccessor _umbracoContextAccessor;
- private readonly SurfaceControllerTypeCollection _surfaceControllerTypes;
- private readonly UmbracoApiControllerTypeCollection _apiControllerTypes;
private readonly IGlobalSettings _globalSettings;
- public WebInitialComponent(
- IUmbracoContextAccessor umbracoContextAccessor,
- SurfaceControllerTypeCollection surfaceControllerTypes,
- UmbracoApiControllerTypeCollection apiControllerTypes,
- IGlobalSettings globalSettings)
+ public WebInitialComponent(IGlobalSettings globalSettings)
{
- _umbracoContextAccessor = umbracoContextAccessor;
- _surfaceControllerTypes = surfaceControllerTypes;
- _apiControllerTypes = apiControllerTypes;
_globalSettings = globalSettings;
}
@@ -63,9 +51,6 @@ namespace Umbraco.Web.Runtime
// add global filters
ConfigureGlobalFilters();
-
- // set routes
- CreateRoutes(_umbracoContextAccessor, _globalSettings, _surfaceControllerTypes, _apiControllerTypes);
}
public void Terminate()
@@ -90,94 +75,6 @@ namespace Umbraco.Web.Runtime
}
}
- // internal for tests
- internal static void CreateRoutes(
- IUmbracoContextAccessor umbracoContextAccessor,
- IGlobalSettings globalSettings,
- SurfaceControllerTypeCollection surfaceControllerTypes,
- UmbracoApiControllerTypeCollection apiControllerTypes)
- {
- var umbracoPath = globalSettings.GetUmbracoMvcArea();
-
- // create the front-end route
- var defaultRoute = RouteTable.Routes.MapRoute(
- "Umbraco_default",
- umbracoPath + "/RenderMvc/{action}/{id}",
- new { controller = "RenderMvc", action = "Index", id = UrlParameter.Optional }
- );
- defaultRoute.RouteHandler = new RenderRouteHandler(umbracoContextAccessor, ControllerBuilder.Current.GetControllerFactory());
-
- // register install routes
- RouteTable.Routes.RegisterArea();
-
- // register all back office routes
- RouteTable.Routes.RegisterArea(new BackOfficeArea(globalSettings));
-
- // plugin controllers must come first because the next route will catch many things
- RoutePluginControllers(globalSettings, surfaceControllerTypes, apiControllerTypes);
- }
-
- private static void RoutePluginControllers(
- IGlobalSettings globalSettings,
- SurfaceControllerTypeCollection surfaceControllerTypes,
- UmbracoApiControllerTypeCollection apiControllerTypes)
- {
- var umbracoPath = globalSettings.GetUmbracoMvcArea();
-
- // need to find the plugin controllers and route them
- var pluginControllers = surfaceControllerTypes.Concat(apiControllerTypes).ToArray();
-
- // local controllers do not contain the attribute
- var localControllers = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace());
- foreach (var s in localControllers)
- {
- if (TypeHelper.IsTypeAssignableFrom(s))
- RouteLocalSurfaceController(s, umbracoPath);
- else if (TypeHelper.IsTypeAssignableFrom(s))
- RouteLocalApiController(s, umbracoPath);
- }
-
- // get the plugin controllers that are unique to each area (group by)
- var pluginSurfaceControlleres = pluginControllers.Where(x => PluginController.GetMetadata(x).AreaName.IsNullOrWhiteSpace() == false);
- var groupedAreas = pluginSurfaceControlleres.GroupBy(controller => PluginController.GetMetadata(controller).AreaName);
- // loop through each area defined amongst the controllers
- foreach (var g in groupedAreas)
- {
- // create & register an area for the controllers (this will throw an exception if all controllers are not in the same area)
- var pluginControllerArea = new PluginControllerArea(globalSettings, g.Select(PluginController.GetMetadata));
- RouteTable.Routes.RegisterArea(pluginControllerArea);
- }
- }
-
- private static void RouteLocalApiController(Type controller, string umbracoPath)
- {
- var meta = PluginController.GetMetadata(controller);
- var url = umbracoPath + (meta.IsBackOffice ? "/BackOffice" : "") + "/Api/" + meta.ControllerName + "/{action}/{id}";
- var route = RouteTable.Routes.MapHttpRoute(
- $"umbraco-api-{meta.ControllerName}",
- url, // url to match
- new { controller = meta.ControllerName, id = UrlParameter.Optional },
- new[] { meta.ControllerNamespace });
- if (route.DataTokens == null) // web api routes don't set the data tokens object
- route.DataTokens = new RouteValueDictionary();
- route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "api"); //ensure the umbraco token is set
- }
-
- private static void RouteLocalSurfaceController(Type controller, string umbracoPath)
- {
- var meta = PluginController.GetMetadata(controller);
- var url = umbracoPath + "/Surface/" + meta.ControllerName + "/{action}/{id}";
- var route = RouteTable.Routes.MapRoute(
- $"umbraco-surface-{meta.ControllerName}",
- url, // url to match
- new { controller = meta.ControllerName, action = "Index", id = UrlParameter.Optional },
- new[] { meta.ControllerNamespace }); // look in this namespace to create the controller
- route.DataTokens.Add(Core.Constants.Web.UmbracoDataToken, "surface"); // ensure the umbraco token is set
- route.DataTokens.Add("UseNamespaceFallback", false); // don't look anywhere else except this namespace!
- // make it use our custom/special SurfaceMvcHandler
- route.RouteHandler = new SurfaceRouteHandler();
- }
-
private static void SetupMvcAndWebApi()
{
//don't output the MVC version header (security)