diff --git a/src/Umbraco.Core/PublishedCache/IPublishedContentCache.cs b/src/Umbraco.Core/PublishedCache/IPublishedContentCache.cs
index 8353225f10..8230b0f306 100644
--- a/src/Umbraco.Core/PublishedCache/IPublishedContentCache.cs
+++ b/src/Umbraco.Core/PublishedCache/IPublishedContentCache.cs
@@ -11,7 +11,7 @@ public interface IPublishedContentCache : IPublishedCache
/// A value indicating whether to consider unpublished content.
/// The content, or null.
/// Considers published or unpublished content depending on defaults.
- Task GetByIdAsync(int id, bool preview = false);
+ Task GetByIdAsync(int id, bool? preview = null);
///
/// Gets a content identified by its unique identifier.
@@ -20,7 +20,7 @@ public interface IPublishedContentCache : IPublishedCache
/// A value indicating whether to consider unpublished content.
/// The content, or null.
/// Considers published or unpublished content depending on defaults.
- Task GetByIdAsync(Guid key, bool preview = false);
+ Task GetByIdAsync(Guid key, bool? preview = null);
// FIXME: All these routing methods needs to be removed, as they are no longer part of the content cache
///
diff --git a/src/Umbraco.Core/Services/IPreviewService.cs b/src/Umbraco.Core/Services/IPreviewService.cs
index c9e276d83e..c65dbe16bb 100644
--- a/src/Umbraco.Core/Services/IPreviewService.cs
+++ b/src/Umbraco.Core/Services/IPreviewService.cs
@@ -15,5 +15,7 @@ public interface IPreviewService
///
Task EndPreviewAsync();
+ bool IsInPreview();
+
Task> TryGetPreviewClaimsIdentityAsync();
}
diff --git a/src/Umbraco.Core/Services/PreviewService.cs b/src/Umbraco.Core/Services/PreviewService.cs
index bc11ab53bf..c487d4d407 100644
--- a/src/Umbraco.Core/Services/PreviewService.cs
+++ b/src/Umbraco.Core/Services/PreviewService.cs
@@ -1,5 +1,6 @@
using System.Security.Claims;
using Microsoft.Extensions.DependencyInjection;
+using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Preview;
using Umbraco.Cms.Core.Security;
@@ -13,15 +14,18 @@ public class PreviewService : IPreviewService
private readonly ICookieManager _cookieManager;
private readonly IPreviewTokenGenerator _previewTokenGenerator;
private readonly IServiceScopeFactory _serviceScopeFactory;
+ private readonly IRequestCache _requestCache;
public PreviewService(
ICookieManager cookieManager,
IPreviewTokenGenerator previewTokenGenerator,
- IServiceScopeFactory serviceScopeFactory)
+ IServiceScopeFactory serviceScopeFactory,
+ IRequestCache requestCache)
{
_cookieManager = cookieManager;
_previewTokenGenerator = previewTokenGenerator;
_serviceScopeFactory = serviceScopeFactory;
+ _requestCache = requestCache;
}
public async Task TryEnterPreviewAsync(IUser user)
@@ -42,6 +46,11 @@ public class PreviewService : IPreviewService
return Task.CompletedTask;
}
+ public bool IsInPreview() =>
+ _requestCache.Get(
+ "IsInPreview",
+ () => TryGetPreviewClaimsIdentityAsync().GetAwaiter().GetResult().Success) as bool? ?? false;
+
public async Task> TryGetPreviewClaimsIdentityAsync()
{
var cookieValue = _cookieManager.GetCookieValue(Constants.Web.PreviewCookieName);
diff --git a/src/Umbraco.PublishedCache.HybridCache/DocumentCache.cs b/src/Umbraco.PublishedCache.HybridCache/DocumentCache.cs
index d978919a65..9be78a9ea2 100644
--- a/src/Umbraco.PublishedCache.HybridCache/DocumentCache.cs
+++ b/src/Umbraco.PublishedCache.HybridCache/DocumentCache.cs
@@ -21,19 +21,19 @@ public sealed class DocumentCache : IPublishedContentCache
_publishedContentTypeCache = publishedContentTypeCache;
}
- public async Task GetByIdAsync(int id, bool preview = false) => await _documentCacheService.GetByIdAsync(id, preview);
+ public async Task GetByIdAsync(int id, bool? preview = null) => await _documentCacheService.GetByIdAsync(id, preview);
- public async Task GetByIdAsync(Guid key, bool preview = false) => await _documentCacheService.GetByKeyAsync(key, preview);
+ public async Task GetByIdAsync(Guid key, bool? preview = null) => await _documentCacheService.GetByKeyAsync(key, preview);
public IPublishedContent? GetById(bool preview, int contentId) => GetByIdAsync(contentId, preview).GetAwaiter().GetResult();
public IPublishedContent? GetById(bool preview, Guid contentId) => GetByIdAsync(contentId, preview).GetAwaiter().GetResult();
- public IPublishedContent? GetById(int contentId) => GetByIdAsync(contentId, false).GetAwaiter().GetResult();
+ public IPublishedContent? GetById(int contentId) => GetByIdAsync(contentId).GetAwaiter().GetResult();
- public IPublishedContent? GetById(Guid contentId) => GetByIdAsync(contentId, false).GetAwaiter().GetResult();
+ public IPublishedContent? GetById(Guid contentId) => GetByIdAsync(contentId).GetAwaiter().GetResult();
public IPublishedContentType? GetContentType(int id) => _publishedContentTypeCache.Get(PublishedItemType.Content, id);
diff --git a/src/Umbraco.PublishedCache.HybridCache/Services/DocumentCacheService.cs b/src/Umbraco.PublishedCache.HybridCache/Services/DocumentCacheService.cs
index 4b8628574f..b73f48dcd7 100644
--- a/src/Umbraco.PublishedCache.HybridCache/Services/DocumentCacheService.cs
+++ b/src/Umbraco.PublishedCache.HybridCache/Services/DocumentCacheService.cs
@@ -22,6 +22,7 @@ internal sealed class DocumentCacheService : IDocumentCacheService
private readonly ICacheNodeFactory _cacheNodeFactory;
private readonly IEnumerable _seedKeyProviders;
private readonly IPublishedModelFactory _publishedModelFactory;
+ private readonly IPreviewService _previewService;
private readonly CacheSettings _cacheSettings;
private HashSet? _seedKeys;
@@ -54,7 +55,8 @@ internal sealed class DocumentCacheService : IDocumentCacheService
ICacheNodeFactory cacheNodeFactory,
IEnumerable seedKeyProviders,
IOptions cacheSettings,
- IPublishedModelFactory publishedModelFactory)
+ IPublishedModelFactory publishedModelFactory,
+ IPreviewService previewService)
{
_databaseCacheRepository = databaseCacheRepository;
_idKeyMap = idKeyMap;
@@ -64,22 +66,30 @@ internal sealed class DocumentCacheService : IDocumentCacheService
_cacheNodeFactory = cacheNodeFactory;
_seedKeyProviders = seedKeyProviders;
_publishedModelFactory = publishedModelFactory;
+ _previewService = previewService;
_cacheSettings = cacheSettings.Value;
}
- public async Task GetByKeyAsync(Guid key, bool preview = false)
+ public async Task GetByKeyAsync(Guid key, bool? preview = null)
{
using ICoreScope scope = _scopeProvider.CreateCoreScope();
+ bool calculatedPreview = preview ?? GetPreview();
+
ContentCacheNode? contentCacheNode = await _hybridCache.GetOrCreateAsync(
- GetCacheKey(key, preview), // Unique key to the cache entry
- async cancel => await _databaseCacheRepository.GetContentSourceAsync(key, preview));
+ GetCacheKey(key, calculatedPreview), // Unique key to the cache entry
+ async cancel => await _databaseCacheRepository.GetContentSourceAsync(key, calculatedPreview));
scope.Complete();
- return contentCacheNode is null ? null : _publishedContentFactory.ToIPublishedContent(contentCacheNode, preview).CreateModel(_publishedModelFactory);
+ return contentCacheNode is null ? null : _publishedContentFactory.ToIPublishedContent(contentCacheNode, calculatedPreview).CreateModel(_publishedModelFactory);
}
- public async Task GetByIdAsync(int id, bool preview = false)
+ private bool GetPreview()
+ {
+ return _previewService.IsInPreview();
+ }
+
+ public async Task GetByIdAsync(int id, bool? preview = null)
{
Attempt keyAttempt = _idKeyMap.GetKeyForId(id, UmbracoObjectTypes.Document);
if (keyAttempt.Success is false)
@@ -87,12 +97,14 @@ internal sealed class DocumentCacheService : IDocumentCacheService
return null;
}
+ bool calculatedPreview = preview ?? GetPreview();
+
using ICoreScope scope = _scopeProvider.CreateCoreScope();
ContentCacheNode? contentCacheNode = await _hybridCache.GetOrCreateAsync(
- GetCacheKey(keyAttempt.Result, preview), // Unique key to the cache entry
- async cancel => await _databaseCacheRepository.GetContentSourceAsync(id, preview));
+ GetCacheKey(keyAttempt.Result, calculatedPreview), // Unique key to the cache entry
+ async cancel => await _databaseCacheRepository.GetContentSourceAsync(id, calculatedPreview));
scope.Complete();
- return contentCacheNode is null ? null : _publishedContentFactory.ToIPublishedContent(contentCacheNode, preview).CreateModel(_publishedModelFactory);;
+ return contentCacheNode is null ? null : _publishedContentFactory.ToIPublishedContent(contentCacheNode, calculatedPreview).CreateModel(_publishedModelFactory);;
}
public IEnumerable GetByContentType(IPublishedContentType contentType)
diff --git a/src/Umbraco.PublishedCache.HybridCache/Services/IDocumentCacheService.cs b/src/Umbraco.PublishedCache.HybridCache/Services/IDocumentCacheService.cs
index 873551c06b..18a25496e2 100644
--- a/src/Umbraco.PublishedCache.HybridCache/Services/IDocumentCacheService.cs
+++ b/src/Umbraco.PublishedCache.HybridCache/Services/IDocumentCacheService.cs
@@ -5,9 +5,9 @@ namespace Umbraco.Cms.Infrastructure.HybridCache.Services;
public interface IDocumentCacheService
{
- Task GetByKeyAsync(Guid key, bool preview = false);
+ Task GetByKeyAsync(Guid key, bool? preview = null);
- Task GetByIdAsync(int id, bool preview = false);
+ Task GetByIdAsync(int id, bool? preview = null);
Task SeedAsync(CancellationToken cancellationToken);
diff --git a/tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/DocumentHybridCacheMockTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/DocumentHybridCacheMockTests.cs
index b0e3bc6ec7..2e810114d0 100644
--- a/tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/DocumentHybridCacheMockTests.cs
+++ b/tests/Umbraco.Tests.Integration/Umbraco.PublishedCache.HybridCache/DocumentHybridCacheMockTests.cs
@@ -104,7 +104,8 @@ public class DocumentHybridCacheMockTests : UmbracoIntegrationTestWithContent
GetRequiredService(),
GetSeedProviders(),
Options.Create(new CacheSettings()),
- GetRequiredService());
+ GetRequiredService(),
+ GetRequiredService());
_mockedCache = new DocumentCache(_mockDocumentCacheService, GetRequiredService());
}