diff --git a/src/Umbraco.Core/Routing/CreatingRequestNotification.cs b/src/Umbraco.Core/Routing/CreatingRequestNotification.cs new file mode 100644 index 0000000000..859ccd24b0 --- /dev/null +++ b/src/Umbraco.Core/Routing/CreatingRequestNotification.cs @@ -0,0 +1,21 @@ +using System; +using Umbraco.Core.Events; + +namespace Umbraco.Web.Routing +{ + /// + /// Used for notifying when an Umbraco request is being created + /// + public class CreatingRequestNotification : INotification + { + /// + /// Initializes a new instance of the class. + /// + public CreatingRequestNotification(Uri url) => Url = url; + + /// + /// Gets or sets the URL for the request + /// + public Uri Url { get; set; } + } +} diff --git a/src/Umbraco.Core/Routing/IPublishedRouter.cs b/src/Umbraco.Core/Routing/IPublishedRouter.cs index aaccb4b4d2..2a6f6b66d9 100644 --- a/src/Umbraco.Core/Routing/IPublishedRouter.cs +++ b/src/Umbraco.Core/Routing/IPublishedRouter.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using Umbraco.Core.Models; namespace Umbraco.Web.Routing @@ -16,21 +17,21 @@ namespace Umbraco.Web.Routing /// /// The current request Uri. /// A published request builder. - IPublishedRequestBuilder CreateRequest(Uri uri); + Task CreateRequestAsync(Uri uri); /// /// Prepares a request for rendering. /// /// The request. /// A value indicating whether the request was successfully prepared and can be rendered. - IPublishedRequest RouteRequest(IPublishedRequestBuilder request); + Task RouteRequestAsync(IPublishedRequestBuilder request); /// /// Tries to route a request. /// /// The request. /// A value indicating whether the request can be routed to a document. - bool TryRouteRequest(IPublishedRequestBuilder request); + Task TryRouteRequestAsync(IPublishedRequestBuilder request); // TODO: This shouldn't be required and should be handled differently during route building ///// diff --git a/src/Umbraco.Core/Routing/PublishedRouter.cs b/src/Umbraco.Core/Routing/PublishedRouter.cs index 8d5c2774ed..ae77abe4a7 100644 --- a/src/Umbraco.Core/Routing/PublishedRouter.cs +++ b/src/Umbraco.Core/Routing/PublishedRouter.cs @@ -3,10 +3,12 @@ using System.Globalization; using System.IO; using System.Linq; using System.Threading; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Umbraco.Core; using Umbraco.Core.Configuration.Models; +using Umbraco.Core.Events; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; @@ -16,6 +18,7 @@ using Umbraco.Web.Security; namespace Umbraco.Web.Routing { + /// /// Provides the default implementation. /// @@ -35,6 +38,7 @@ namespace Umbraco.Web.Routing private readonly IContentTypeService _contentTypeService; private readonly IPublicAccessService _publicAccessService; private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IEventAggregator _eventAggregator; /// /// Initializes a new instance of the class. @@ -53,7 +57,8 @@ namespace Umbraco.Web.Routing IFileService fileService, IContentTypeService contentTypeService, IPublicAccessService publicAccessService, - IUmbracoContextAccessor umbracoContextAccessor) + IUmbracoContextAccessor umbracoContextAccessor, + IEventAggregator eventAggregator) { _webRoutingSettings = webRoutingSettings.Value ?? throw new ArgumentNullException(nameof(webRoutingSettings)); _contentFinders = contentFinders ?? throw new ArgumentNullException(nameof(contentFinders)); @@ -69,31 +74,52 @@ namespace Umbraco.Web.Routing _contentTypeService = contentTypeService; _publicAccessService = publicAccessService; _umbracoContextAccessor = umbracoContextAccessor; + _eventAggregator = eventAggregator; } /// - public IPublishedRequestBuilder CreateRequest(Uri uri) => new PublishedRequestBuilder(uri, _fileService); + public async Task CreateRequestAsync(Uri uri) + { + // trigger the Creating event - at that point the URL can be changed + // this is based on this old task here: https://issues.umbraco.org/issue/U4-7914 which was fulfiled by + // this PR https://github.com/umbraco/Umbraco-CMS/pull/1137 + // It's to do with proxies, quote: + + /* + "Thinking about another solution. + We already have an event, PublishedContentRequest.Prepared, which triggers once the request has been prepared and domain, content, template have been figured out -- but before it renders -- so ppl can change things before rendering. + Wondering whether we could have a event, PublishedContentRequest.Preparing, which would trigger before the request is prepared, and would let ppl change the value of the request's URI (which by default derives from the HttpContext request). + That way, if an in-between equipement changes the URI, you could replace it with the original, public-facing URI before we process the request, meaning you could register your HTTPS domain and it would work. And you would have to supply code for each equipment. Less magic in Core." + */ + + // but now we'll just have one event for creating so if people wish to change the URL here they can but nothing else + var creatingRequest = new CreatingRequestNotification(uri); + await _eventAggregator.PublishAsync(creatingRequest); + + var publishedRequestBuilder = new PublishedRequestBuilder(creatingRequest.Url, _fileService); + return publishedRequestBuilder; + } /// - public bool TryRouteRequest(IPublishedRequestBuilder request) + public Task TryRouteRequestAsync(IPublishedRequestBuilder request) { FindDomain(request); // TODO: This was ported from v8 but how could it possibly have a redirect here? if (request.IsRedirect()) { - return false; + return Task.FromResult(false); } // TODO: This was ported from v8 but how could it possibly have content here? if (request.HasPublishedContent()) { - return true; + return Task.FromResult(true); } FindPublishedContent(request); - return request.Build().Success(); + return Task.FromResult(request.Build().Success()); } private void SetVariationContext(CultureInfo culture) @@ -112,12 +138,8 @@ namespace Umbraco.Web.Routing } /// - public IPublishedRequest RouteRequest(IPublishedRequestBuilder request) + public async Task RouteRequestAsync(IPublishedRequestBuilder request) { - //// trigger the Preparing event - at that point anything can still be changed - //// the idea is that it is possible to change the uri - //request.OnPreparing(); - // find domain FindDomain(request); @@ -146,10 +168,10 @@ namespace Umbraco.Web.Routing // set the culture -- again, 'cos it might have changed due to a finder or wildcard domain SetVariationContext(request.Culture); - //// trigger the Prepared event - at that point it is still possible to change about anything - //// even though the request might be flagged for redirection - we'll redirect _after_ the event - //// also, OnPrepared() will make the PublishedRequest readonly, so nothing can change - //request.OnPrepared(); + // trigger the routing request (used to be called Prepared) event - at that point it is still possible to change about anything + // even though the request might be flagged for redirection - we'll redirect _after_ the event + var routingRequest = new RoutingRequestNotification(request); + await _eventAggregator.PublishAsync(routingRequest); // we don't take care of anything so if the content has changed, it's up to the user // to find out the appropriate template diff --git a/src/Umbraco.Core/Routing/RoutingRequestNotification.cs b/src/Umbraco.Core/Routing/RoutingRequestNotification.cs new file mode 100644 index 0000000000..dbf1cbc15b --- /dev/null +++ b/src/Umbraco.Core/Routing/RoutingRequestNotification.cs @@ -0,0 +1,20 @@ +using Umbraco.Core.Events; + +namespace Umbraco.Web.Routing +{ + /// + /// Used for notifying when an Umbraco request is being built + /// + public class RoutingRequestNotification : INotification + { + /// + /// Initializes a new instance of the class. + /// + public RoutingRequestNotification(IPublishedRequestBuilder requestBuilder) => RequestBuilder = requestBuilder; + + /// + /// Gets the + /// + public IPublishedRequestBuilder RequestBuilder { get; } + } +} diff --git a/src/Umbraco.Core/Routing/UrlProviderExtensions.cs b/src/Umbraco.Core/Routing/UrlProviderExtensions.cs index 19d65b8f3a..e7095feb2b 100644 --- a/src/Umbraco.Core/Routing/UrlProviderExtensions.cs +++ b/src/Umbraco.Core/Routing/UrlProviderExtensions.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; -using Umbraco.Core.Models; -using Umbraco.Core.Services; using Umbraco.Core; +using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Services; namespace Umbraco.Web.Routing { @@ -18,7 +19,8 @@ namespace Umbraco.Web.Routing /// Use when displaying URLs. If errors occur when generating the URLs, they will show in the list. /// Contains all the URLs that we can figure out (based upon domains, etc). /// - public static IEnumerable GetContentUrls(this IContent content, + public static async Task> GetContentUrlsAsync( + this IContent content, IPublishedRouter publishedRouter, IUmbracoContext umbracoContext, ILocalizationService localizationService, @@ -40,10 +42,12 @@ namespace Umbraco.Web.Routing if (uriUtility == null) throw new ArgumentNullException(nameof(uriUtility)); if (variationContextAccessor == null) throw new ArgumentNullException(nameof(variationContextAccessor)); + var result = new List(); + if (content.Published == false) { - yield return UrlInfo.Message(textService.Localize("content/itemNotPublished")); - yield break; + result.Add(UrlInfo.Message(textService.Localize("content/itemNotPublished"))); + return result; } // build a list of URLs, for the back-office @@ -57,47 +61,47 @@ namespace Umbraco.Web.Routing // for URLs for all cultures. // and, not only for those assigned to domains in the branch, because we want // to show what GetUrl() would return, for every culture. - var urls = new HashSet(); var cultures = localizationService.GetAllLanguages().Select(x => x.IsoCode).ToList(); - //get all URLs for all cultures - //in a HashSet, so de-duplicates too - foreach (var cultureUrl in GetContentUrlsByCulture(content, cultures, publishedRouter, umbracoContext, contentService, textService, variationContextAccessor, logger, uriUtility, publishedUrlProvider)) + // get all URLs for all cultures + // in a HashSet, so de-duplicates too + foreach (UrlInfo cultureUrl in await GetContentUrlsByCultureAsync(content, cultures, publishedRouter, umbracoContext, contentService, textService, variationContextAccessor, logger, uriUtility, publishedUrlProvider)) { urls.Add(cultureUrl); } - //return the real URLs first, then the messages - foreach (var urlGroup in urls.GroupBy(x => x.IsUrl).OrderByDescending(x => x.Key)) + // return the real URLs first, then the messages + foreach (IGrouping urlGroup in urls.GroupBy(x => x.IsUrl).OrderByDescending(x => x.Key)) { - //in some cases there will be the same URL for multiple cultures: + // in some cases there will be the same URL for multiple cultures: // * The entire branch is invariant // * If there are less domain/cultures assigned to the branch than the number of cultures/languages installed - - foreach (var dUrl in urlGroup.DistinctBy(x => x.Text.ToUpperInvariant()).OrderBy(x => x.Text).ThenBy(x => x.Culture)) - yield return dUrl; + foreach (UrlInfo dUrl in urlGroup.DistinctBy(x => x.Text.ToUpperInvariant()).OrderBy(x => x.Text).ThenBy(x => x.Culture)) + { + result.Add(dUrl); + } } // get the 'other' URLs - ie not what you'd get with GetUrl() but URLs that would route to the document, nevertheless. // for these 'other' URLs, we don't check whether they are routable, collide, anything - we just report them. foreach (var otherUrl in publishedUrlProvider.GetOtherUrls(content.Id).OrderBy(x => x.Text).ThenBy(x => x.Culture)) - if (urls.Add(otherUrl)) //avoid duplicates - yield return otherUrl; + { + // avoid duplicates + if (urls.Add(otherUrl)) + { + result.Add(otherUrl); + } + } + + return result; } /// /// Tries to return a for each culture for the content while detecting collisions/errors /// - /// - /// - /// - /// - /// - /// - /// - /// - private static IEnumerable GetContentUrlsByCulture(IContent content, + private static async Task> GetContentUrlsByCultureAsync( + IContent content, IEnumerable cultures, IPublishedRouter publishedRouter, IUmbracoContext umbracoContext, @@ -108,14 +112,17 @@ namespace Umbraco.Web.Routing UriUtility uriUtility, IPublishedUrlProvider publishedUrlProvider) { + var result = new List(); + foreach (var culture in cultures) { // if content is variant, and culture is not published, skip if (content.ContentType.VariesByCulture() && !content.IsCulturePublished(culture)) + { continue; + } // if it's variant and culture is published, or if it's invariant, proceed - string url; try { @@ -131,47 +138,63 @@ namespace Umbraco.Web.Routing { // deal with 'could not get the URL' case "#": - yield return HandleCouldNotGetUrl(content, culture, contentService, textService); + result.Add(HandleCouldNotGetUrl(content, culture, contentService, textService)); break; // deal with exceptions case "#ex": - yield return UrlInfo.Message(textService.Localize("content/getUrlException"), culture); + result.Add(UrlInfo.Message(textService.Localize("content/getUrlException"), culture)); break; // got a URL, deal with collisions, add URL default: - if (DetectCollision(content, url, culture, umbracoContext, publishedRouter, textService, variationContextAccessor, uriUtility, out var urlInfo)) // detect collisions, etc - yield return urlInfo; + // detect collisions, etc + Attempt hasCollision = await DetectCollisionAsync(content, url, culture, umbracoContext, publishedRouter, textService, variationContextAccessor, uriUtility); + if (hasCollision) + { + result.Add(hasCollision.Result); + } else - yield return UrlInfo.Url(url, culture); + { + result.Add(UrlInfo.Url(url, culture)); + } + break; } } + + return result; } private static UrlInfo HandleCouldNotGetUrl(IContent content, string culture, IContentService contentService, ILocalizedTextService textService) { // document has a published version yet its URL is "#" => a parent must be // unpublished, walk up the tree until we find it, and report. - var parent = content; + IContent parent = content; do { parent = parent.ParentId > 0 ? contentService.GetParent(parent) : null; } while (parent != null && parent.Published && (!parent.ContentType.VariesByCulture() || parent.IsCulturePublished(culture))); - if (parent == null) // oops, internal error + if (parent == null) + { + // oops, internal error return UrlInfo.Message(textService.Localize("content/parentNotPublishedAnomaly"), culture); - - else if (!parent.Published) // totally not published + } + else if (!parent.Published) + { + // totally not published return UrlInfo.Message(textService.Localize("content/parentNotPublished", new[] {parent.Name}), culture); - - else // culture not published + } + else + { + // culture not published return UrlInfo.Message(textService.Localize("content/parentCultureNotPublished", new[] {parent.Name}), culture); + } } - private static bool DetectCollision(IContent content, string url, string culture, IUmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, IVariationContextAccessor variationContextAccessor, UriUtility uriUtility, out UrlInfo urlInfo) + private static async Task> DetectCollisionAsync(IContent content, string url, string culture, IUmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, IVariationContextAccessor variationContextAccessor, UriUtility uriUtility) { // test for collisions on the 'main' URL var uri = new Uri(url.TrimEnd('/'), UriKind.RelativeOrAbsolute); @@ -181,15 +204,13 @@ namespace Umbraco.Web.Routing } uri = uriUtility.UriToUmbraco(uri); - IPublishedRequestBuilder pcr = publishedRouter.CreateRequest(uri); - publishedRouter.TryRouteRequest(pcr); - - urlInfo = null; + IPublishedRequestBuilder pcr = await publishedRouter.CreateRequestAsync(uri); + var routeResult = await publishedRouter.TryRouteRequestAsync(pcr); if (pcr.PublishedContent == null) { - urlInfo = UrlInfo.Message(textService.Localize("content/routeErrorCannotRoute"), culture); - return true; + var urlInfo = UrlInfo.Message(textService.Localize("content/routeErrorCannotRoute"), culture); + return Attempt.Succeed(urlInfo); } // TODO: What is this? @@ -211,12 +232,12 @@ namespace Umbraco.Web.Routing l.Reverse(); var s = "/" + string.Join("/", l) + " (id=" + pcr.PublishedContent.Id + ")"; - urlInfo = UrlInfo.Message(textService.Localize("content/routeError", new[] { s }), culture); - return true; + var urlInfo = UrlInfo.Message(textService.Localize("content/routeError", new[] { s }), culture); + return Attempt.Succeed(urlInfo); } // no collision - return false; + return Attempt.Fail(); } } } diff --git a/src/Umbraco.Core/Templates/ITemplateRenderer.cs b/src/Umbraco.Core/Templates/ITemplateRenderer.cs index f01edc58ed..7a6248e034 100644 --- a/src/Umbraco.Core/Templates/ITemplateRenderer.cs +++ b/src/Umbraco.Core/Templates/ITemplateRenderer.cs @@ -1,4 +1,5 @@ -using System.IO; +using System.IO; +using System.Threading.Tasks; namespace Umbraco.Web.Templates { @@ -7,6 +8,6 @@ namespace Umbraco.Web.Templates /// public interface ITemplateRenderer { - void Render(int pageId, int? altTemplateId, StringWriter writer); + Task RenderAsync(int pageId, int? altTemplateId, StringWriter writer); } } diff --git a/src/Umbraco.Core/Templates/UmbracoComponentRenderer.cs b/src/Umbraco.Core/Templates/UmbracoComponentRenderer.cs index 4618eb2822..53e856ced4 100644 --- a/src/Umbraco.Core/Templates/UmbracoComponentRenderer.cs +++ b/src/Umbraco.Core/Templates/UmbracoComponentRenderer.cs @@ -43,7 +43,7 @@ namespace Umbraco.Core.Templates { try { - _templateRenderer.Render(contentId, altTemplateId, sw); + _templateRenderer.RenderAsync(contentId, altTemplateId, sw); } catch (Exception ex) { diff --git a/src/Umbraco.Tests/PublishedContent/PublishedRouterTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedRouterTests.cs index 3621580dcb..02ccc69f80 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedRouterTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedRouterTests.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Collections.ObjectModel; using System.Globalization; using System.Linq; +using System.Threading.Tasks; using Moq; using NUnit.Framework; using Umbraco.Core.Models; @@ -16,22 +17,22 @@ namespace Umbraco.Tests.PublishedContent public class PublishedRouterTests : BaseWebTest { [Test] - public void ConfigureRequest_Returns_False_Without_HasPublishedContent() + public async Task ConfigureRequest_Returns_False_Without_HasPublishedContent() { var umbracoContext = GetUmbracoContext("/test"); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var request = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var request = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); var result = publishedRouter.ConfigureRequest(request); Assert.IsFalse(result.Success()); } [Test] - public void ConfigureRequest_Returns_False_When_IsRedirect() + public async Task ConfigureRequest_Returns_False_When_IsRedirect() { var umbracoContext = GetUmbracoContext("/test"); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var request = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var request = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); var content = GetPublishedContentMock(); request.SetPublishedContent(content.Object); request.SetCulture(new CultureInfo("en-AU")); diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs index 34051c96bd..e510dd8381 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasTests.cs @@ -8,6 +8,7 @@ using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; using Umbraco.Web.Routing; +using System.Threading.Tasks; namespace Umbraco.Tests.Routing { @@ -45,11 +46,11 @@ namespace Umbraco.Tests.Routing [TestCase("/only/one/alias", 100111)] [TestCase("/ONLY/one/Alias", 100111)] [TestCase("/alias43", 100121)] - public void Lookup_By_Url_Alias(string urlAsString, int nodeMatch) + public async Task Lookup_By_Url_Alias(string urlAsString, int nodeMatch) { var umbracoContext = GetUmbracoContext(urlAsString); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); var lookup = new ContentFinderByUrlAlias(LoggerFactory.CreateLogger(), Mock.Of(), VariationContextAccessor, GetUmbracoContextAccessor(umbracoContext)); diff --git a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs index 5a390f667c..4746720329 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByAliasWithDomainsTests.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; @@ -52,13 +53,13 @@ namespace Umbraco.Tests.Routing [TestCase("http://domain1.com/bar/foo", "de-DE", 100111)] // ok [TestCase("http://domain1.com/en/bar/foo", "en-US", -100111)] // no, alias must include "en/" [TestCase("http://domain1.com/en/bar/nil", "en-US", 100111)] // ok, alias includes "en/" - public void Lookup_By_Url_Alias_And_Domain(string inputUrl, string expectedCulture, int expectedNode) + public async Task Lookup_By_Url_Alias_And_Domain(string inputUrl, string expectedCulture, int expectedNode) { //SetDomains1(); var umbracoContext = GetUmbracoContext(inputUrl); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var request = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var request = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); // must lookup domain publishedRouter.FindDomain(request); diff --git a/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs index 0ed3161caf..a484597c9c 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByIdTests.cs @@ -6,20 +6,20 @@ using Umbraco.Core.Configuration.Models; using Umbraco.Tests.TestHelpers; using Umbraco.Web; using Umbraco.Web.Routing; +using System.Threading.Tasks; namespace Umbraco.Tests.Routing { [TestFixture] public class ContentFinderByIdTests : BaseWebTest { - [TestCase("/1046", 1046)] [TestCase("/1046.aspx", 1046)] - public void Lookup_By_Id(string urlAsString, int nodeMatch) + public async Task Lookup_By_Id(string urlAsString, int nodeMatch) { var umbracoContext = GetUmbracoContext(urlAsString); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); var webRoutingSettings = new WebRoutingSettings(); var lookup = new ContentFinderByIdPath(Microsoft.Extensions.Options.Options.Create(webRoutingSettings), LoggerFactory.CreateLogger(), Factory.GetRequiredService(), GetUmbracoContextAccessor(umbracoContext)); diff --git a/src/Umbraco.Tests/Routing/ContentFinderByPageIdQueryTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByPageIdQueryTests.cs index 24872a128e..05f4ee67b7 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByPageIdQueryTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByPageIdQueryTests.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using Moq; using NUnit.Framework; using Umbraco.Tests.TestHelpers; @@ -14,12 +15,12 @@ namespace Umbraco.Tests.Routing [TestCase("/default.aspx?umbPageId=1046", 1046)] // TODO: Should this match?? [TestCase("/some/other/page?umbPageId=1046", 1046)] // TODO: Should this match?? [TestCase("/some/other/page.aspx?umbPageId=1046", 1046)] // TODO: Should this match?? - public void Lookup_By_Page_Id(string urlAsString, int nodeMatch) + public async Task Lookup_By_Page_Id(string urlAsString, int nodeMatch) { var umbracoContext = GetUmbracoContext(urlAsString); var httpContext = GetHttpContextFactory(urlAsString).HttpContext; var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); var mockRequestAccessor = new Mock(); mockRequestAccessor.Setup(x => x.GetRequestValue("umbPageID")).Returns(httpContext.Request.QueryString["umbPageID"]); diff --git a/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs index 82b433a1a0..959836d3ff 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByUrlAndTemplateTests.cs @@ -5,6 +5,7 @@ using Umbraco.Web.Routing; using Umbraco.Core.Configuration.Models; using Umbraco.Core.Models; using Umbraco.Tests.Testing; +using System.Threading.Tasks; namespace Umbraco.Tests.Routing { @@ -25,7 +26,7 @@ namespace Umbraco.Tests.Routing [TestCase("/home/Sub1/blah")] [TestCase("/Home/Sub1/Blah")] //different cases [TestCase("/home/Sub1.aspx/blah")] - public void Match_Document_By_Url_With_Template(string urlAsString) + public async Task Match_Document_By_Url_With_Template(string urlAsString) { var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false }; @@ -33,7 +34,7 @@ namespace Umbraco.Tests.Routing var template2 = CreateTemplate("blah"); var umbracoContext = GetUmbracoContext(urlAsString, template1.Id, globalSettings: globalSettings); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var reqBuilder = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var reqBuilder = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); var webRoutingSettings = new WebRoutingSettings(); var lookup = new ContentFinderByUrlAndTemplate( LoggerFactory.CreateLogger(), diff --git a/src/Umbraco.Tests/Routing/ContentFinderByUrlTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByUrlTests.cs index 807cf729ef..2b5364c22a 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByUrlTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByUrlTests.cs @@ -8,6 +8,7 @@ using Umbraco.Web.Routing; using Microsoft.Extensions.Logging; using Umbraco.Web; using Moq; +using System.Threading.Tasks; namespace Umbraco.Tests.Routing { @@ -26,14 +27,14 @@ namespace Umbraco.Tests.Routing // we've made it return "/test-page" => we have to support that URL back in the lookup... [TestCase("/home", 1046)] [TestCase("/test-page", 1172)] - public void Match_Document_By_Url_Hide_Top_Level(string urlString, int expectedId) + public async Task Match_Document_By_Url_Hide_Top_Level(string urlString, int expectedId) { var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = true }; var snapshotService = CreatePublishedSnapshotService(globalSettings); var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettings, snapshotService: snapshotService); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger(), GetUmbracoContextAccessor(umbracoContext)); Assert.IsTrue(globalSettings.HideTopLevelNodeFromPath); @@ -61,13 +62,13 @@ namespace Umbraco.Tests.Routing [TestCase("/home/Sub1", 1173)] [TestCase("/Home/Sub1", 1173)] //different cases [TestCase("/home/Sub1.aspx", 1173)] - public void Match_Document_By_Url(string urlString, int expectedId) + public async Task Match_Document_By_Url(string urlString, int expectedId) { var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false }; var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettings); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger(), GetUmbracoContextAccessor(umbracoContext)); Assert.IsFalse(globalSettings.HideTopLevelNodeFromPath); @@ -85,13 +86,13 @@ namespace Umbraco.Tests.Routing [TestCase("/", 1046)] [TestCase("/home/sub1/custom-sub-3-with-accént-character", 1179)] [TestCase("/home/sub1/custom-sub-4-with-æøå", 1180)] - public void Match_Document_By_Url_With_Special_Characters(string urlString, int expectedId) + public async Task Match_Document_By_Url_With_Special_Characters(string urlString, int expectedId) { var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false }; var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettings); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger(), GetUmbracoContextAccessor(umbracoContext)); var result = lookup.TryFindContent(frequest); @@ -111,13 +112,13 @@ namespace Umbraco.Tests.Routing [TestCase("/", 1046)] [TestCase("/home/sub1/custom-sub-3-with-accént-character", 1179)] [TestCase("/home/sub1/custom-sub-4-with-æøå", 1180)] - public void Match_Document_By_Url_With_Special_Characters_Using_Hostname(string urlString, int expectedId) + public async Task Match_Document_By_Url_With_Special_Characters_Using_Hostname(string urlString, int expectedId) { var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false }; var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettings); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); frequest.SetDomain(new DomainAndUri(new Domain(1, "mysite", -1, CultureInfo.CurrentCulture, false), new Uri("http://mysite/"))); var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger(), GetUmbracoContextAccessor(umbracoContext)); @@ -139,13 +140,13 @@ namespace Umbraco.Tests.Routing [TestCase("/æøå/home/sub1", 1173)] [TestCase("/æøå/home/sub1/custom-sub-3-with-accént-character", 1179)] [TestCase("/æøå/home/sub1/custom-sub-4-with-æøå", 1180)] - public void Match_Document_By_Url_With_Special_Characters_In_Hostname(string urlString, int expectedId) + public async Task Match_Document_By_Url_With_Special_Characters_In_Hostname(string urlString, int expectedId) { var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false }; var umbracoContext = GetUmbracoContext(urlString, globalSettings:globalSettings); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); frequest.SetDomain(new DomainAndUri(new Domain(1, "mysite/æøå", -1, CultureInfo.CurrentCulture, false), new Uri("http://mysite/æøå"))); var lookup = new ContentFinderByUrl(LoggerFactory.CreateLogger(), GetUmbracoContextAccessor(umbracoContext)); diff --git a/src/Umbraco.Tests/Routing/ContentFinderByUrlWithDomainsTests.cs b/src/Umbraco.Tests/Routing/ContentFinderByUrlWithDomainsTests.cs index 84f86f1e09..12115ba3ad 100644 --- a/src/Umbraco.Tests/Routing/ContentFinderByUrlWithDomainsTests.cs +++ b/src/Umbraco.Tests/Routing/ContentFinderByUrlWithDomainsTests.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Models; using Umbraco.Tests.Common.Builders; using Umbraco.Tests.TestHelpers; using Umbraco.Web.Routing; +using System.Threading.Tasks; namespace Umbraco.Tests.Routing { @@ -126,7 +127,7 @@ namespace Umbraco.Tests.Routing [TestCase("http://domain1.com/1001-1", 10011)] [TestCase("http://domain1.com/1001-2/1001-2-1", 100121)] - public void Lookup_SingleDomain(string url, int expectedId) + public async Task Lookup_SingleDomain(string url, int expectedId) { SetDomains3(); @@ -134,7 +135,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(url, globalSettings:globalSettings); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext), Factory); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); // must lookup domain else lookup by URL fails publishedRouter.FindDomain(frequest); @@ -164,7 +165,7 @@ namespace Umbraco.Tests.Routing [TestCase("https://domain1.com/", 1001, "en-US")] [TestCase("https://domain3.com/", 1001, "")] // because domain3 is explicitely set on http - public void Lookup_NestedDomains(string url, int expectedId, string expectedCulture) + public async Task Lookup_NestedDomains(string url, int expectedId, string expectedCulture) { SetDomains4(); @@ -175,7 +176,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(url, globalSettings:globalSettings); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext), Factory); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); // must lookup domain else lookup by URL fails publishedRouter.FindDomain(frequest); diff --git a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs index 4d5111df08..dd5fd6351d 100644 --- a/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs +++ b/src/Umbraco.Tests/Routing/DomainsAndCulturesTests.cs @@ -5,6 +5,7 @@ using Umbraco.Core.Models; using Umbraco.Web.Routing; using Umbraco.Core; using Umbraco.Core.Configuration.Models; +using System.Threading.Tasks; namespace Umbraco.Tests.Routing { @@ -261,7 +262,7 @@ namespace Umbraco.Tests.Routing [TestCase("http://domain1.com/fr", "fr-FR", 10012)] [TestCase("http://domain1.com/fr/1001-2-1", "fr-FR", 100121)] #endregion - public void DomainAndCulture(string inputUrl, string expectedCulture, int expectedNode) + public async Task DomainAndCulture(string inputUrl, string expectedCulture, int expectedNode) { SetDomains1(); @@ -269,7 +270,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(inputUrl, globalSettings:globalSettings); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext), Factory); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); // lookup domain publishedRouter.FindDomain(frequest); @@ -306,7 +307,7 @@ namespace Umbraco.Tests.Routing [TestCase("/1003/1003-1", "nl-NL", 10031)] // wildcard on 10031 applies [TestCase("/1003/1003-1/1003-1-1", "nl-NL", 100311)] // wildcard on 10031 applies #endregion - public void DomainAndCultureWithWildcards(string inputUrl, string expectedCulture, int expectedNode) + public async Task DomainAndCultureWithWildcards(string inputUrl, string expectedCulture, int expectedNode) { SetDomains2(); @@ -317,7 +318,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(inputUrl, globalSettings:globalSettings); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext), Factory); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); // lookup domain publishedRouter.FindDomain(frequest); @@ -363,14 +364,14 @@ namespace Umbraco.Tests.Routing [TestCase("http://domain1.com/fr", "fr-FR", 10012)] [TestCase("http://domain1.com/fr/1001-2-1", "fr-FR", 100121)] #endregion - public void DomainGeneric(string inputUrl, string expectedCulture, int expectedNode) + public async Task DomainGeneric(string inputUrl, string expectedCulture, int expectedNode) { SetDomains3(); var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false }; var umbracoContext = GetUmbracoContext(inputUrl, globalSettings:globalSettings); var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext), Factory); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); // lookup domain publishedRouter.FindDomain(frequest); diff --git a/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs b/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs index 31bbd06ade..7cb9983155 100644 --- a/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs +++ b/src/Umbraco.Tests/Routing/GetContentUrlsTests.cs @@ -11,6 +11,7 @@ using Umbraco.Tests.Common; using Umbraco.Tests.TestHelpers.Entities; using Umbraco.Web.Routing; using Microsoft.Extensions.Logging; +using System.Threading.Tasks; namespace Umbraco.Tests.Routing { @@ -55,7 +56,7 @@ namespace Umbraco.Tests.Routing } [Test] - public void Content_Not_Published() + public async Task Content_Not_Published() { var contentType = MockedContentTypes.CreateBasicContentType(); var content = MockedContent.CreateBasicContent(contentType); @@ -67,13 +68,13 @@ namespace Umbraco.Tests.Routing GetUmbracoContextAccessor(umbContext), Factory, contentFinders: new ContentFinderCollection(new[] { new ContentFinderByUrl(LoggerFactory.CreateLogger(), GetUmbracoContextAccessor(umbContext)) })); - var urls = content.GetContentUrls(publishedRouter, + var urls = (await content.GetContentUrlsAsync(publishedRouter, umbContext, GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, VariationContextAccessor, LoggerFactory.CreateLogger(), UriUtility, - PublishedUrlProvider).ToList(); + PublishedUrlProvider)).ToList(); Assert.AreEqual(1, urls.Count); Assert.AreEqual("content/itemNotPublished", urls[0].Text); @@ -81,7 +82,7 @@ namespace Umbraco.Tests.Routing } [Test] - public void Invariant_Root_Content_Published_No_Domains() + public async Task Invariant_Root_Content_Published_No_Domains() { var contentType = MockedContentTypes.CreateBasicContentType(); var content = MockedContent.CreateBasicContent(contentType); @@ -108,13 +109,13 @@ namespace Umbraco.Tests.Routing umbracoContextAccessor, Factory, contentFinders:new ContentFinderCollection(new[]{new ContentFinderByUrl(LoggerFactory.CreateLogger(), umbracoContextAccessor) })); - var urls = content.GetContentUrls(publishedRouter, + var urls = (await content.GetContentUrlsAsync(publishedRouter, umbContext, GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, VariationContextAccessor, LoggerFactory.CreateLogger(), UriUtility, - publishedUrlProvider).ToList(); + publishedUrlProvider)).ToList(); Assert.AreEqual(1, urls.Count); Assert.AreEqual("/home/", urls[0].Text); @@ -123,7 +124,7 @@ namespace Umbraco.Tests.Routing } [Test] - public void Invariant_Child_Content_Published_No_Domains() + public async Task Invariant_Child_Content_Published_No_Domains() { var contentType = MockedContentTypes.CreateBasicContentType(); var parent = MockedContent.CreateBasicContent(contentType); @@ -155,14 +156,14 @@ namespace Umbraco.Tests.Routing umbracoContextAccessor, Factory, contentFinders: new ContentFinderCollection(new[] { new ContentFinderByUrl(LoggerFactory.CreateLogger(), umbracoContextAccessor) })); - var urls = child.GetContentUrls(publishedRouter, + var urls = (await child.GetContentUrlsAsync(publishedRouter, umbContext, GetLangService("en-US", "fr-FR"), GetTextService(), ServiceContext.ContentService, VariationContextAccessor, LoggerFactory.CreateLogger(), UriUtility, publishedUrlProvider - ).ToList(); + )).ToList(); Assert.AreEqual(1, urls.Count); Assert.AreEqual("/home/sub1/", urls[0].Text); diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index 63e8180aff..7edb316c2e 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -27,6 +27,7 @@ using Umbraco.Web.Runtime; using Umbraco.Web.WebApi; using Current = Umbraco.Web.Composing.Current; using Umbraco.Core.DependencyInjection; +using System.Threading.Tasks; namespace Umbraco.Tests.Routing { @@ -83,7 +84,7 @@ namespace Umbraco.Tests.Routing /// Will route to the default controller and action since no custom controller is defined for this node route /// [Test] - public void Umbraco_Route_Umbraco_Defined_Controller_Action() + public async Task Umbraco_Route_Umbraco_Defined_Controller_Action() { var url = "~/dummy-page"; var template = CreateTemplate("homePage"); @@ -92,7 +93,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext(url, template.Id, routeData); var httpContext = GetHttpContextFactory(url, routeData).HttpContext; var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); frequest.SetPublishedContent(umbracoContext.Content.GetById(1174)); frequest.SetTemplate(template); @@ -117,7 +118,7 @@ namespace Umbraco.Tests.Routing [TestCase("homePage")] [TestCase("site1/template2")] [TestCase("site1\\template2")] - public void Umbraco_Route_User_Defined_Controller_Action(string templateName) + public async Task Umbraco_Route_User_Defined_Controller_Action(string templateName) { // NOTE - here we create templates with crazy aliases... assuming that these // could exist in the database... yet creating templates should sanitize @@ -130,7 +131,7 @@ namespace Umbraco.Tests.Routing var umbracoContext = GetUmbracoContext("~/dummy-page", template.Id, routeData, true); var httpContext = GetHttpContextFactory(url, routeData).HttpContext; var publishedRouter = CreatePublishedRouter(GetUmbracoContextAccessor(umbracoContext)); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); frequest.SetPublishedContent(umbracoContext.Content.GetById(1172)); frequest.SetTemplate(template); diff --git a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs index cdc62b1a35..73b6f17d19 100644 --- a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs +++ b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs @@ -13,6 +13,7 @@ using Umbraco.Tests.LegacyXmlPublishedCache; using Umbraco.Web; using Umbraco.Web.Routing; using Umbraco.Core.DependencyInjection; +using System.Threading.Tasks; namespace Umbraco.Tests.Routing { @@ -32,7 +33,7 @@ namespace Umbraco.Tests.Routing } [Test] - public void DoNotPolluteCache() + public async Task DoNotPolluteCache() { var requestHandlerSettings = new RequestHandlerSettings { AddTrailingSlash = true }; var globalSettings = new GlobalSettings { HideTopLevelNodeFromPath = false }; @@ -60,7 +61,7 @@ namespace Umbraco.Tests.Routing // route a rogue URL var publishedRouter = CreatePublishedRouter(umbracoContextAccessor); - var frequest = publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var frequest = await publishedRouter .CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); publishedRouter.FindDomain(frequest); Assert.IsTrue(frequest.HasDomain()); diff --git a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs index e7ccc01acb..719c785fd7 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseWebTest.cs @@ -8,6 +8,7 @@ using Moq; using NUnit.Framework; using Umbraco.Core.Configuration.Models; using Umbraco.Core.DependencyInjection; +using Umbraco.Core.Events; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; @@ -114,7 +115,8 @@ namespace Umbraco.Tests.TestHelpers container?.GetRequiredService() ?? Current.Factory.GetRequiredService(), container?.GetRequiredService() ?? Current.Factory.GetRequiredService(), container?.GetRequiredService() ?? Current.Factory.GetRequiredService(), - umbracoContextAccessor + umbracoContextAccessor, + Mock.Of() ); } } diff --git a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs index 3e5e799dba..09748e9621 100644 --- a/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs +++ b/src/Umbraco.Tests/Web/Mvc/SurfaceControllerTests.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using System.Web; using System.Web.Mvc; using System.Web.Routing; @@ -126,7 +127,7 @@ namespace Umbraco.Tests.Web.Mvc } [Test] - public void Mock_Current_Page() + public async Task Mock_Current_Page() { var globalSettings = TestObjects.GetGlobalSettings(); var httpContextAccessor = TestHelper.GetHttpContextAccessor(); @@ -152,7 +153,7 @@ namespace Umbraco.Tests.Web.Mvc var webRoutingSettings = new WebRoutingSettings(); var publishedRouter = BaseWebTest.CreatePublishedRouter(umbracoContextAccessor, webRoutingSettings); - var frequest = publishedRouter.CreateRequest(new Uri("http://localhost/test")); + var frequest = await publishedRouter.CreateRequestAsync(new Uri("http://localhost/test")); frequest.SetPublishedContent(content); var routeDefinition = new RouteDefinition diff --git a/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs b/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs index 3e81bde207..9d610b81f0 100644 --- a/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs +++ b/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Microsoft.Extensions.Logging; @@ -199,13 +199,21 @@ namespace Umbraco.Web.BackOffice.Mapping private UrlInfo[] GetUrls(IContent source) { if (source.ContentType.IsElement) + { return Array.Empty(); + } var umbracoContext = _umbracoContextAccessor.UmbracoContext; - var urls = umbracoContext == null - ? new[] { UrlInfo.Message("Cannot generate URLs without a current Umbraco Context") } - : source.GetContentUrls(_publishedRouter, umbracoContext, _localizationService, _localizedTextService, _contentService, _variationContextAccessor, _loggerFactory.CreateLogger(), _uriUtility, _publishedUrlProvider).ToArray(); + if (umbracoContext == null) + { + return new[] { UrlInfo.Message("Cannot generate URLs without a current Umbraco Context") }; + } + + // NOTE: unfortunately we're not async, we'll use .Result and hope this won't cause a deadlock anywhere for now + var urls = source.GetContentUrlsAsync(_publishedRouter, umbracoContext, _localizationService, _localizedTextService, _contentService, _variationContextAccessor, _loggerFactory.CreateLogger(), _uriUtility, _publishedUrlProvider) + .Result + .ToArray(); return urls; } diff --git a/src/Umbraco.Web.Common/Templates/TemplateRenderer.cs b/src/Umbraco.Web.Common/Templates/TemplateRenderer.cs index 654eb8f8d7..d9b7bf95a4 100644 --- a/src/Umbraco.Web.Common/Templates/TemplateRenderer.cs +++ b/src/Umbraco.Web.Common/Templates/TemplateRenderer.cs @@ -2,6 +2,7 @@ using System; using System.Globalization; using System.IO; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Controllers; @@ -14,11 +15,9 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Umbraco.Core; using Umbraco.Core.Configuration.Models; -using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Services; using Umbraco.Core.Strings; using Umbraco.Extensions; -using Umbraco.Web.Models; using Umbraco.Web.Routing; using Umbraco.Web.Templates; @@ -41,7 +40,8 @@ namespace Umbraco.Web.Common.Templates private readonly IHttpContextAccessor _httpContextAccessor; private readonly ICompositeViewEngine _viewEngine; - public TemplateRenderer(IUmbracoContextAccessor umbracoContextAccessor, + public TemplateRenderer( + IUmbracoContextAccessor umbracoContextAccessor, IPublishedRouter publishedRouter, IFileService fileService, ILocalizationService textService, @@ -60,7 +60,7 @@ namespace Umbraco.Web.Common.Templates _viewEngine = viewEngine ?? throw new ArgumentNullException(nameof(viewEngine)); } - public void Render(int pageId, int? altTemplateId, StringWriter writer) + public async Task RenderAsync(int pageId, int? altTemplateId, StringWriter writer) { if (writer == null) throw new ArgumentNullException(nameof(writer)); @@ -69,7 +69,7 @@ namespace Umbraco.Web.Common.Templates // instantiate a request and process // important to use CleanedUmbracoUrl - lowercase path-only version of the current URL, though this isn't going to matter // terribly much for this implementation since we are just creating a doc content request to modify it's properties manually. - var requestBuilder = _publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + var requestBuilder = await _publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); var doc = umbracoContext.Content.GetById(pageId); diff --git a/src/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformer.cs b/src/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformer.cs index dc72777fa8..4916faeece 100644 --- a/src/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformer.cs +++ b/src/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformer.cs @@ -102,7 +102,7 @@ namespace Umbraco.Web.Website.Routing return await Task.FromResult(values); } - RouteRequest(_umbracoContextAccessor.UmbracoContext, out IPublishedRequest publishedRequest); + IPublishedRequest publishedRequest = await RouteRequestAsync(_umbracoContextAccessor.UmbracoContext); UmbracoRouteValues routeDef = GetUmbracoRouteDefinition(httpContext, values, publishedRequest); @@ -228,23 +228,19 @@ namespace Umbraco.Web.Website.Routing return descriptors; } - private bool RouteRequest(IUmbracoContext umbracoContext, out IPublishedRequest publishedRequest) + private async Task RouteRequestAsync(IUmbracoContext umbracoContext) { - // TODO: I suspect one day this will be async - // ok, process // instantiate, prepare and process the published content request // important to use CleanedUmbracoUrl - lowercase path-only version of the current url - IPublishedRequestBuilder requestBuilder = _publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); + IPublishedRequestBuilder requestBuilder = await _publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl); // TODO: This is ugly with the re-assignment to umbraco context but at least its now // an immutable object. The only way to make this better would be to have a RouteRequest // as part of UmbracoContext but then it will require a PublishedRouter dependency so not sure that's worth it. // Maybe could be a one-time Set method instead? - publishedRequest = umbracoContext.PublishedRequest = _publishedRouter.RouteRequest(requestBuilder); - - return publishedRequest.Success(); + return umbracoContext.PublishedRequest = await _publishedRouter.RouteRequestAsync(requestBuilder); // // HandleHttpResponseStatus returns a value indicating that the request should // // not be processed any further, eg because it has been redirect. then, exit. diff --git a/src/Umbraco.Web/UmbracoInjectedModule.cs b/src/Umbraco.Web/UmbracoInjectedModule.cs index 308e7dd48e..aef8b4bc3e 100644 --- a/src/Umbraco.Web/UmbracoInjectedModule.cs +++ b/src/Umbraco.Web/UmbracoInjectedModule.cs @@ -135,8 +135,8 @@ namespace Umbraco.Web // instantiate, prepare and process the published content request // important to use CleanedUmbracoUrl - lowercase path-only version of the current URL - var requestBuilder = _publishedRouter.CreateRequest(umbracoContext.CleanedUmbracoUrl); - var request = umbracoContext.PublishedRequest = _publishedRouter.RouteRequest(requestBuilder); + var requestBuilder = _publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl).Result; + var request = umbracoContext.PublishedRequest = _publishedRouter.RouteRequestAsync(requestBuilder).Result; // NOTE: This has been ported to netcore // HandleHttpResponseStatus returns a value indicating that the request should