V13: Set request culture for VirtualPageController (#16572)
* Rename FindDomain to FindAndSetDomain * Ensure VariationContext and PublishedRequest is updated for virtual page controller
This commit is contained in:
@@ -47,4 +47,37 @@ public interface IPublishedRouter
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
Task<IPublishedRequest> UpdateRequestAsync(IPublishedRequest request, IPublishedContent? publishedContent);
|
||||
|
||||
/// <summary>
|
||||
/// Finds the site root (if any) matching the http request, and updates the PublishedRequest and VariationContext accordingly.
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This method is used for VirtualPage routing.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// In this case we do not want to run the entire routing pipeline since ContentFinders are not needed here.
|
||||
/// However, we do want to set the culture on VariationContext and PublishedRequest to the values specified by the domains.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// </summary>
|
||||
/// <param name="request">The request to update the culture on domain on</param>
|
||||
/// <returns>True if a domain was found otherwise false.</returns>
|
||||
bool RouteDomain(IPublishedRequestBuilder request) => false;
|
||||
|
||||
/// <summary>
|
||||
/// Finds the site root (if any) matching the http request, and updates the VariationContext accordingly.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This is used for VirtualPage routing.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// This is required to set the culture on VariationContext to the values specified by the domains, before the FindContent method is called.
|
||||
/// In order to allow the FindContent implementer to correctly find content based off the culture. Before the PublishedRequest is built.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="uri">The URI to resolve the domain from.</param>
|
||||
/// <returns>True if a domain was found, otherwise false.</returns>
|
||||
bool UpdateVariationContext(Uri uri) => false;
|
||||
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ public class PublishedRouter : IPublishedRouter
|
||||
// find domain
|
||||
if (builder.Domain == null)
|
||||
{
|
||||
FindDomain(builder);
|
||||
FindAndSetDomain(builder);
|
||||
}
|
||||
|
||||
await RouteRequestInternalAsync(builder);
|
||||
@@ -185,7 +185,7 @@ public class PublishedRouter : IPublishedRouter
|
||||
|
||||
private async Task<IPublishedRequest> TryRouteRequest(IPublishedRequestBuilder request)
|
||||
{
|
||||
FindDomain(request);
|
||||
FindAndSetDomain(request);
|
||||
|
||||
if (request.IsRedirect())
|
||||
{
|
||||
@@ -270,18 +270,31 @@ public class PublishedRouter : IPublishedRouter
|
||||
// to find out the appropriate template
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the site root (if any) matching the http request, and updates the PublishedRequest accordingly.
|
||||
/// </summary>
|
||||
/// <returns>A value indicating whether a domain was found.</returns>
|
||||
internal bool FindDomain(IPublishedRequestBuilder request)
|
||||
/// <inheritdoc />
|
||||
public bool RouteDomain(IPublishedRequestBuilder request)
|
||||
{
|
||||
var found = FindAndSetDomain(request);
|
||||
HandleWildcardDomains(request);
|
||||
SetVariationContext(request.Culture);
|
||||
return found;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool UpdateVariationContext(Uri uri)
|
||||
{
|
||||
DomainAndUri? domain = FindDomain(uri, out _);
|
||||
SetVariationContext(domain?.Culture);
|
||||
return domain?.Culture is not null;
|
||||
}
|
||||
|
||||
private DomainAndUri? FindDomain(Uri uri, out string? defaultCulture)
|
||||
{
|
||||
const string tracePrefix = "FindDomain: ";
|
||||
|
||||
// note - we are not handling schemes nor ports here.
|
||||
if (_logger.IsEnabled(LogLevel.Debug))
|
||||
{
|
||||
_logger.LogDebug("{TracePrefix}Uri={RequestUri}", tracePrefix, request.Uri);
|
||||
_logger.LogDebug("{TracePrefix}Uri={RequestUri}", tracePrefix, uri);
|
||||
}
|
||||
|
||||
IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
@@ -315,10 +328,20 @@ public class PublishedRouter : IPublishedRouter
|
||||
|
||||
domains = domains?.Where(IsPublishedContentDomain).ToList();
|
||||
|
||||
var defaultCulture = domainsCache?.DefaultCulture;
|
||||
defaultCulture = domainsCache?.DefaultCulture;
|
||||
|
||||
return DomainUtilities.SelectDomain(domains, uri, defaultCulture: defaultCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds the site root (if any) matching the http request, and updates the PublishedRequest accordingly.
|
||||
/// </summary>
|
||||
/// <returns>A value indicating whether a domain was found.</returns>
|
||||
internal bool FindAndSetDomain(IPublishedRequestBuilder request)
|
||||
{
|
||||
const string tracePrefix = "FindDomain: ";
|
||||
// try to find a domain matching the current request
|
||||
DomainAndUri? domainAndUri = DomainUtilities.SelectDomain(domains, request.Uri, defaultCulture: defaultCulture);
|
||||
DomainAndUri? domainAndUri = FindDomain(request.Uri, out var defaultCulture);
|
||||
|
||||
// handle domain - always has a contentId and a culture
|
||||
if (domainAndUri != null)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Web.Common.Controllers;
|
||||
using Umbraco.Cms.Web.Common.Routing;
|
||||
|
||||
@@ -40,6 +42,12 @@ public class UmbracoVirtualPageFilterAttribute : Attribute, IAsyncActionFilter
|
||||
if (endpoint != null)
|
||||
{
|
||||
IUmbracoVirtualPageRoute umbracoVirtualPageRoute = context.HttpContext.RequestServices.GetRequiredService<IUmbracoVirtualPageRoute>();
|
||||
IPublishedRouter publishedRouter = context.HttpContext.RequestServices.GetRequiredService<IPublishedRouter>();
|
||||
UriUtility uriUtility = context.HttpContext.RequestServices.GetRequiredService<UriUtility>();
|
||||
|
||||
var originalRequestUrl = new Uri(context.HttpContext.Request.GetEncodedUrl());
|
||||
Uri cleanedUri = uriUtility.UriToUmbraco(originalRequestUrl);
|
||||
publishedRouter.UpdateVariationContext(cleanedUri);
|
||||
|
||||
IPublishedContent? publishedContent = umbracoVirtualPageRoute.FindContent(endpoint, context);
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ public class UmbracoVirtualPageRoute : IUmbracoVirtualPageRoute
|
||||
|
||||
IPublishedRequestBuilder requestBuilder = await _publishedRouter.CreateRequestAsync(cleanedUrl);
|
||||
requestBuilder.SetPublishedContent(publishedContent);
|
||||
_publishedRouter.RouteDomain(requestBuilder);
|
||||
|
||||
return requestBuilder.Build();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class ContentFinderByAliasWithDomainsTests : UrlRoutingTestBase
|
||||
var request = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
// must lookup domain
|
||||
publishedRouter.FindDomain(request);
|
||||
publishedRouter.FindAndSetDomain(request);
|
||||
|
||||
if (expectedNode > 0)
|
||||
{
|
||||
|
||||
@@ -207,7 +207,7 @@ public class ContentFinderByUrlWithDomainsTests : UrlRoutingTestBase
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
// must lookup domain else lookup by URL fails
|
||||
publishedRouter.FindDomain(frequest);
|
||||
publishedRouter.FindAndSetDomain(frequest);
|
||||
|
||||
var lookup = new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor);
|
||||
var result = await lookup.TryFindContent(frequest);
|
||||
@@ -245,7 +245,7 @@ public class ContentFinderByUrlWithDomainsTests : UrlRoutingTestBase
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
// must lookup domain else lookup by URL fails
|
||||
publishedRouter.FindDomain(frequest);
|
||||
publishedRouter.FindAndSetDomain(frequest);
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture);
|
||||
|
||||
var lookup = new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor);
|
||||
|
||||
@@ -261,7 +261,7 @@ public class DomainsAndCulturesTests : UrlRoutingTestBase
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
// lookup domain
|
||||
publishedRouter.FindDomain(frequest);
|
||||
publishedRouter.FindAndSetDomain(frequest);
|
||||
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture);
|
||||
|
||||
@@ -310,7 +310,7 @@ public class DomainsAndCulturesTests : UrlRoutingTestBase
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
// lookup domain
|
||||
publishedRouter.FindDomain(frequest);
|
||||
publishedRouter.FindAndSetDomain(frequest);
|
||||
|
||||
// find document
|
||||
var finder = new ContentFinderByUrl(Mock.Of<ILogger<ContentFinderByUrl>>(), umbracoContextAccessor);
|
||||
@@ -345,7 +345,7 @@ public class DomainsAndCulturesTests : UrlRoutingTestBase
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
// lookup domain
|
||||
publishedRouter.FindDomain(frequest);
|
||||
publishedRouter.FindAndSetDomain(frequest);
|
||||
Assert.IsNotNull(frequest.Domain);
|
||||
|
||||
Assert.AreEqual(expectedCulture, frequest.Culture);
|
||||
|
||||
@@ -62,7 +62,7 @@ public class UrlsWithNestedDomains : UrlRoutingTestBase
|
||||
var publishedRouter = CreatePublishedRouter(umbracoContextAccessor);
|
||||
var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
|
||||
publishedRouter.FindDomain(frequest);
|
||||
publishedRouter.FindAndSetDomain(frequest);
|
||||
Assert.IsTrue(frequest.HasDomain());
|
||||
|
||||
// check that it's been routed
|
||||
|
||||
Reference in New Issue
Block a user