diff --git a/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs b/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs index 8cc104b79e..532ff13583 100644 --- a/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs +++ b/src/Umbraco.Core/Web/HybridUmbracoContextAccessor.cs @@ -31,5 +31,6 @@ namespace Umbraco.Cms.Core.Web return umbracoContext is not null; } public void Clear() => Value = null; + public void Set(IUmbracoContext umbracoContext) => Value = umbracoContext; } } diff --git a/src/Umbraco.Core/Web/IUmbracoContextAccessor.cs b/src/Umbraco.Core/Web/IUmbracoContextAccessor.cs index 18cd5f7e02..06e29f1349 100644 --- a/src/Umbraco.Core/Web/IUmbracoContextAccessor.cs +++ b/src/Umbraco.Core/Web/IUmbracoContextAccessor.cs @@ -8,5 +8,6 @@ namespace Umbraco.Cms.Core.Web IUmbracoContext UmbracoContext { get; set; } bool TryGetUmbracoContext(out IUmbracoContext umbracoContext); void Clear(); + void Set(IUmbracoContext umbracoContext); } } diff --git a/src/Umbraco.Tests.Common/TestUmbracoContextAccessor.cs b/src/Umbraco.Tests.Common/TestUmbracoContextAccessor.cs index 046e232068..31cb36fba9 100644 --- a/src/Umbraco.Tests.Common/TestUmbracoContextAccessor.cs +++ b/src/Umbraco.Tests.Common/TestUmbracoContextAccessor.cs @@ -25,5 +25,6 @@ namespace Umbraco.Cms.Tests.Common } public void Clear() => UmbracoContext = null; + public void Set(IUmbracoContext umbracoContext) => UmbracoContext = umbracoContext; } } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Routing/ContentFinderByUrlAliasTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Routing/ContentFinderByUrlAliasTests.cs index d4c1e303e9..1ad49a95d9 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Core/Routing/ContentFinderByUrlAliasTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Core/Routing/ContentFinderByUrlAliasTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using AutoFixture.NUnit3; using Moq; using NUnit.Framework; @@ -44,7 +44,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing VariationContext variationContext = new VariationContext(); var contentItem = rootContents[0]; - Mock.Get(umbracoContextAccessor).Setup(x => x.UmbracoContext).Returns(umbracoContext); + Mock.Get(umbracoContextAccessor).Setup(x => x.TryGetUmbracoContext(out umbracoContext)).Returns(true); Mock.Get(umbracoContext).Setup(x => x.Content).Returns(publishedContentCache); Mock.Get(publishedContentCache).Setup(x => x.GetAtRoot(null)).Returns(rootContents); Mock.Get(contentItem).Setup(x => x.Id).Returns(nodeMatch); diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformerTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformerTests.cs index 390f60e5f5..f66a69b6f7 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformerTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformerTests.cs @@ -129,7 +129,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.Website.Routing IUmbracoContext umbracoContext = GetUmbracoContext(false); UmbracoRouteValueTransformer transformer = GetTransformerWithRunState( - Mock.Of(x => x.UmbracoContext == umbracoContext)); + Mock.Of(x => x.TryGetUmbracoContext(out umbracoContext))); RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary()); Assert.AreEqual(2, result.Count); @@ -144,7 +144,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.Website.Routing IPublishedRequest request = Mock.Of(); UmbracoRouteValueTransformer transformer = GetTransformerWithRunState( - Mock.Of(x => x.UmbracoContext == umbracoContext), + Mock.Of(x => x.TryGetUmbracoContext(out umbracoContext)), router: GetRouter(request), routeValuesFactory: GetRouteValuesFactory(request)); @@ -159,7 +159,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.Website.Routing IPublishedRequest request = Mock.Of(); UmbracoRouteValueTransformer transformer = GetTransformerWithRunState( - Mock.Of(x => x.UmbracoContext == umbracoContext), + Mock.Of(x => x.TryGetUmbracoContext(out umbracoContext)), router: GetRouter(request), routeValuesFactory: GetRouteValuesFactory(request)); @@ -179,7 +179,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Web.Website.Routing UmbracoRouteValues routeValues = GetRouteValues(request); UmbracoRouteValueTransformer transformer = GetTransformerWithRunState( - Mock.Of(x => x.UmbracoContext == umbracoContext), + Mock.Of(x => x.TryGetUmbracoContext(out umbracoContext)), router: GetRouter(request), routeValuesFactory: GetRouteValuesFactory(request)); diff --git a/src/Umbraco.Web.BackOffice/Filters/AppendCurrentEventMessagesAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/AppendCurrentEventMessagesAttribute.cs index 152f318c06..8df4192906 100644 --- a/src/Umbraco.Web.BackOffice/Filters/AppendCurrentEventMessagesAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/AppendCurrentEventMessagesAttribute.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; @@ -35,8 +35,10 @@ namespace Umbraco.Cms.Web.BackOffice.Filters { if (context.HttpContext.Response == null) return; if (context.HttpContext.Request.Method.Equals(HttpMethod.Get.ToString(), StringComparison.InvariantCultureIgnoreCase)) return; - var umbracoContext = _umbracoContextAccessor.UmbracoContext; - if (umbracoContext == null) return; + if (!_umbracoContextAccessor.TryGetUmbracoContext(out _)) + { + return; + } if (!(context.Result is ObjectResult obj)) return; diff --git a/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs b/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs index a30b6ba69d..0dd19d7db9 100644 --- a/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs +++ b/src/Umbraco.Web.BackOffice/Mapping/ContentMapDefinition.cs @@ -240,10 +240,7 @@ namespace Umbraco.Cms.Web.BackOffice.Mapping { return Array.Empty(); } - - var umbracoContext = _umbracoContextAccessor.UmbracoContext; - - if (umbracoContext == null) + if (!_umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) { return new[] { UrlInfo.Message("Cannot generate URLs without a current Umbraco Context") }; } @@ -261,7 +258,8 @@ namespace Umbraco.Cms.Web.BackOffice.Mapping private DateTime GetUpdateDate(IContent source, MapperContext context) { // invariant = global date - if (!source.ContentType.VariesByCulture()) return source.UpdateDate; + if (!source.ContentType.VariesByCulture()) + return source.UpdateDate; // variant = depends on culture var culture = context.GetCulture(); @@ -279,7 +277,8 @@ namespace Umbraco.Cms.Web.BackOffice.Mapping private string GetName(IContent source, MapperContext context) { // invariant = only 1 name - if (!source.ContentType.VariesByCulture()) return source.Name; + if (!source.ContentType.VariesByCulture()) + return source.Name; // variant = depends on culture var culture = context.GetCulture(); diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeCookieManager.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeCookieManager.cs index 5d50981f6a..48b0d28dd2 100644 --- a/src/Umbraco.Web.BackOffice/Security/BackOfficeCookieManager.cs +++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeCookieManager.cs @@ -109,8 +109,7 @@ namespace Umbraco.Cms.Web.BackOffice.Security string Microsoft.AspNetCore.Authentication.Cookies.ICookieManager.GetRequestCookie(HttpContext context, string key) { var absPath = context.Request.Path; - - if (_umbracoContextAccessor.UmbracoContext == null || _umbracoRequestPaths.IsClientSideRequest(absPath)) + if (!_umbracoContextAccessor.TryGetUmbracoContext(out _) || _umbracoRequestPaths.IsClientSideRequest(absPath)) { return null; } diff --git a/src/Umbraco.Web.Common/Extensions/PublishedContentExtensions.cs b/src/Umbraco.Web.Common/Extensions/PublishedContentExtensions.cs index 9e04ba8889..edfd30293d 100644 --- a/src/Umbraco.Web.Common/Extensions/PublishedContentExtensions.cs +++ b/src/Umbraco.Web.Common/Extensions/PublishedContentExtensions.cs @@ -75,8 +75,11 @@ namespace Umbraco.Extensions .Field(UmbracoExamineFieldNames.IndexPathFieldName, (content.Path + ",").MultipleCharacterWildcard()) .And() .ManagedQuery(term); - - return query.Execute().ToPublishedSearchResults(umbracoContextAccessor.UmbracoContext.Content); + if (!umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) + { + throw new InvalidOperationException("Wasn't able to get an UmbracoContext"); + } + return query.Execute().ToPublishedSearchResults(umbracoContext.Content); } public static IEnumerable SearchChildren(this IPublishedContent content, IExamineManager examineManager, IUmbracoContextAccessor umbracoContextAccessor, string term, string indexName = null) @@ -94,8 +97,12 @@ namespace Umbraco.Extensions .Field("parentID", content.Id) .And() .ManagedQuery(term); + if (!umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) + { + throw new InvalidOperationException("Wasn't able to get an UmbracoContext"); + } - return query.Execute().ToPublishedSearchResults(umbracoContextAccessor.UmbracoContext.Content); + return query.Execute().ToPublishedSearchResults(umbracoContext.Content); } #endregion diff --git a/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs b/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs index b41d96e0d0..955cb4f7da 100644 --- a/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs +++ b/src/Umbraco.Web.Common/UmbracoContext/UmbracoContextFactory.cs @@ -82,16 +82,15 @@ namespace Umbraco.Cms.Web.Common.UmbracoContext /// public UmbracoContextReference EnsureUmbracoContext() { - IUmbracoContext currentUmbracoContext = _umbracoContextAccessor.UmbracoContext; - if (currentUmbracoContext != null) + if (_umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) { - return new UmbracoContextReference(currentUmbracoContext, false, _umbracoContextAccessor); + return new UmbracoContextReference(umbracoContext, false, _umbracoContextAccessor); } - IUmbracoContext umbracoContext = CreateUmbracoContext(); - _umbracoContextAccessor.UmbracoContext = umbracoContext; + IUmbracoContext createdUmbracoContext = CreateUmbracoContext(); - return new UmbracoContextReference(umbracoContext, true, _umbracoContextAccessor); + _umbracoContextAccessor.Set(createdUmbracoContext); + return new UmbracoContextReference(createdUmbracoContext, true, _umbracoContextAccessor); } } diff --git a/src/Umbraco.Web.Common/Views/UmbracoViewPage.cs b/src/Umbraco.Web.Common/Views/UmbracoViewPage.cs index 97ba933838..d9bed99861 100644 --- a/src/Umbraco.Web.Common/Views/UmbracoViewPage.cs +++ b/src/Umbraco.Web.Common/Views/UmbracoViewPage.cs @@ -78,7 +78,17 @@ namespace Umbraco.Cms.Web.Common.Views /// /// Gets the /// - protected IUmbracoContext UmbracoContext => _umbracoContext ??= UmbracoContextAccessor.UmbracoContext; + protected IUmbracoContext UmbracoContext + { + get + { + if (!UmbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) + { + return null; + } + return umbracoContext; + } + } /// public override ViewContext ViewContext diff --git a/src/Umbraco.Web.Website/Controllers/RenderNoContentController.cs b/src/Umbraco.Web.Website/Controllers/RenderNoContentController.cs index 2546531735..638325fb84 100644 --- a/src/Umbraco.Web.Website/Controllers/RenderNoContentController.cs +++ b/src/Umbraco.Web.Website/Controllers/RenderNoContentController.cs @@ -1,4 +1,4 @@ -using System; +using System; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using Umbraco.Cms.Core.Configuration.Models; @@ -23,7 +23,11 @@ namespace Umbraco.Cms.Web.Website.Controllers public ActionResult Index() { - var store = _umbracoContextAccessor.UmbracoContext.Content; + if (!_umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) + { + throw new InvalidOperationException("Wasn't able to get an UmbracoContext"); + } + var store = umbracoContext.Content; if (store.HasContent()) { // If there is actually content, go to the root. diff --git a/src/Umbraco.Web.Website/Extensions/HtmlHelperRenderExtensions.cs b/src/Umbraco.Web.Website/Extensions/HtmlHelperRenderExtensions.cs index 123ed6801a..2b4f0ac491 100644 --- a/src/Umbraco.Web.Website/Extensions/HtmlHelperRenderExtensions.cs +++ b/src/Umbraco.Web.Website/Extensions/HtmlHelperRenderExtensions.cs @@ -66,15 +66,18 @@ namespace Umbraco.Extensions /// public static IHtmlContent PreviewBadge(this IHtmlHelper helper, IUmbracoContextAccessor umbracoContextAccessor, IHttpContextAccessor httpContextAccessor, GlobalSettings globalSettings, IIOHelper ioHelper, ContentSettings contentSettings) { - var umbrcoContext = umbracoContextAccessor.UmbracoContext; - if (umbrcoContext.InPreviewMode) + if (!umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) + { + throw new InvalidOperationException("Wasn't able to get an UmbracoContext"); + } + if (umbracoContext.InPreviewMode) { var htmlBadge = string.Format( contentSettings.PreviewBadge, ioHelper.ResolveUrl(globalSettings.UmbracoPath), WebUtility.UrlEncode(httpContextAccessor.GetRequiredHttpContext().Request.Path), - umbrcoContext.PublishedRequest.PublishedContent.Id); + umbracoContext.PublishedRequest.PublishedContent.Id); return new HtmlString(htmlBadge); } @@ -102,8 +105,7 @@ namespace Umbraco.Extensions if (cacheByPage) { var umbracoContextAccessor = GetRequiredService(htmlHelper); - var umbracoContext = umbracoContextAccessor.UmbracoContext; - if (umbracoContext == null) + if (!umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) { throw new InvalidOperationException("Cannot cache by page if the UmbracoContext has not been initialized, this parameter can only be used in the context of an Umbraco request"); } @@ -667,7 +669,11 @@ namespace Umbraco.Extensions } IUmbracoContextAccessor umbracoContextAccessor = GetRequiredService(html); - var formAction = umbracoContextAccessor.UmbracoContext.OriginalRequestUrl.PathAndQuery; + if (!umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) + { + throw new InvalidOperationException("Wasn't able to get an UmbracoContext"); + } + var formAction = umbracoContext.OriginalRequestUrl.PathAndQuery; return html.RenderForm(formAction, method, htmlAttributes, controllerName, action, area, additionalRouteVals); } diff --git a/src/Umbraco.Web.Website/Middleware/PublicAccessMiddleware.cs b/src/Umbraco.Web.Website/Middleware/PublicAccessMiddleware.cs index cdf721cfbc..458cb79ba8 100644 --- a/src/Umbraco.Web.Website/Middleware/PublicAccessMiddleware.cs +++ b/src/Umbraco.Web.Website/Middleware/PublicAccessMiddleware.cs @@ -126,7 +126,11 @@ namespace Umbraco.Cms.Web.Website.Middleware { if (pageId != publishedRequest.PublishedContent.Id) { - IPublishedContent publishedContent = _umbracoContextAccessor.UmbracoContext.PublishedSnapshot.Content.GetById(pageId); + if (!_umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) + { + throw new InvalidOperationException("Wasn't able to get an UmbracoContext"); + } + IPublishedContent publishedContent = umbracoContext.PublishedSnapshot.Content.GetById(pageId); if (publishedContent == null) { throw new InvalidOperationException("No content found by id " + pageId); diff --git a/src/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformer.cs b/src/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformer.cs index eceae11462..f184471a39 100644 --- a/src/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformer.cs +++ b/src/Umbraco.Web.Website/Routing/UmbracoRouteValueTransformer.cs @@ -94,11 +94,11 @@ namespace Umbraco.Cms.Web.Website.Routing { return values; } - // will be null for any client side requests like JS, etc... - if (_umbracoContextAccessor.UmbracoContext == null) + if (!_umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext)) { return values; + ; } if (!_routableDocumentFilter.IsDocumentRequest(httpContext.Request.Path)) @@ -107,7 +107,7 @@ namespace Umbraco.Cms.Web.Website.Routing } // Check if there is no existing content and return the no content controller - if (!_umbracoContextAccessor.UmbracoContext.Content.HasContent()) + if (!umbracoContext.Content.HasContent()) { values[ControllerToken] = ControllerExtensions.GetControllerName(); values[ActionToken] = nameof(RenderNoContentController.Index); @@ -115,7 +115,7 @@ namespace Umbraco.Cms.Web.Website.Routing return values; } - IPublishedRequest publishedRequest = await RouteRequestAsync(httpContext, _umbracoContextAccessor.UmbracoContext); + IPublishedRequest publishedRequest = await RouteRequestAsync(httpContext, umbracoContext); UmbracoRouteValues umbracoRouteValues = await _routeValuesFactory.CreateAsync(httpContext, publishedRequest);