Skip to content

Commit 00ca9e0

Browse files
V13: Eaglery route domains for virtual page controllers (#16635)
* Do domain routing eagerly * Cleanup * Fix comment
1 parent 65c76fc commit 00ca9e0

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

src/Umbraco.Web.Website/Routing/EagerMatcherPolicy.cs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
using Umbraco.Cms.Core.Configuration.Models;
99
using Umbraco.Cms.Core.Routing;
1010
using Umbraco.Cms.Core.Services;
11+
using Umbraco.Cms.Core.Web;
1112
using Umbraco.Cms.Web.Common.Controllers;
13+
using Umbraco.Cms.Web.Common.Routing;
1214
using Umbraco.Cms.Web.Website.Controllers;
1315
using Umbraco.Extensions;
1416

@@ -37,6 +39,8 @@ internal class EagerMatcherPolicy : MatcherPolicy, IEndpointSelectorPolicy
3739
private readonly IRuntimeState _runtimeState;
3840
private readonly EndpointDataSource _endpointDataSource;
3941
private readonly UmbracoRequestPaths _umbracoRequestPaths;
42+
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
43+
private readonly IPublishedRouter _publishedRouter;
4044
private GlobalSettings _globalSettings;
4145
private readonly Lazy<Endpoint> _installEndpoint;
4246
private readonly Lazy<Endpoint> _renderEndpoint;
@@ -45,11 +49,15 @@ public EagerMatcherPolicy(
4549
IRuntimeState runtimeState,
4650
EndpointDataSource endpointDataSource,
4751
UmbracoRequestPaths umbracoRequestPaths,
48-
IOptionsMonitor<GlobalSettings> globalSettings)
52+
IOptionsMonitor<GlobalSettings> globalSettings,
53+
IUmbracoContextAccessor umbracoContextAccessor,
54+
IPublishedRouter publishedRouter)
4955
{
5056
_runtimeState = runtimeState;
5157
_endpointDataSource = endpointDataSource;
5258
_umbracoRequestPaths = umbracoRequestPaths;
59+
_umbracoContextAccessor = umbracoContextAccessor;
60+
_publishedRouter = publishedRouter;
5361
_globalSettings = globalSettings.CurrentValue;
5462
globalSettings.OnChange(settings => _globalSettings = settings);
5563
_installEndpoint = new Lazy<Endpoint>(GetInstallEndpoint);
@@ -112,11 +120,22 @@ public async Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
112120
ControllerActionDescriptor? controllerDescriptor = routeEndpoint.Metadata.GetMetadata<ControllerActionDescriptor>();
113121
TypeInfo? controllerTypeInfo = controllerDescriptor?.ControllerTypeInfo;
114122
if (controllerTypeInfo is not null &&
115-
(controllerTypeInfo.IsType<RenderController>() || controllerTypeInfo.IsType<SurfaceController>()))
123+
(controllerTypeInfo.IsType<RenderController>()
124+
|| controllerTypeInfo.IsType<SurfaceController>()))
116125
{
117126
return;
118127
}
119128

129+
// If it's an UmbracoPageController we need to do some domain routing.
130+
// We need to do this in oder to handle cultures for our Dictionary.
131+
// This is because UmbracoPublishedContentCultureProvider is ued to set the Thread.CurrentThread.CurrentUICulture
132+
// The CultureProvider is run before the actual routing, this means that our UmbracoVirtualPageFilterAttribute is hit AFTER the culture is set.
133+
// Meaning we have to route the domain part already now, this is not pretty, but it beats having to look for content we know doesn't exist.
134+
if (controllerTypeInfo is not null && controllerTypeInfo.IsType<UmbracoPageController>())
135+
{
136+
await RouteVirtualRequestAsync(httpContext);
137+
}
138+
120139
if (routeEndpoint.Order < lowestOrder)
121140
{
122141
// We have to ensure that the route is valid for the current request method.
@@ -153,6 +172,22 @@ public async Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
153172
}
154173
}
155174

175+
private async Task RouteVirtualRequestAsync(HttpContext context)
176+
{
177+
if (_umbracoContextAccessor.TryGetUmbracoContext(out IUmbracoContext? umbracoContext) is false)
178+
{
179+
return;
180+
}
181+
182+
IPublishedRequestBuilder requestBuilder =
183+
await _publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
184+
_publishedRouter.RouteDomain(requestBuilder);
185+
// This is just a temporary RouteValues object just for culture which will be overwritten later
186+
// so we can just use a dummy action descriptor.
187+
var umbracoRouteValues = new UmbracoRouteValues(requestBuilder.Build(), new ControllerActionDescriptor());
188+
context.Features.Set(umbracoRouteValues);
189+
}
190+
156191
/// <summary>
157192
/// Replaces the first endpoint candidate with the specified endpoint, invalidating all other candidates,
158193
/// guaranteeing that the specified endpoint will be hit.

0 commit comments

Comments
 (0)