From 218d67a7fd1575e2d8d624e554f6c1a4f4dcc532 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Tue, 7 Oct 2025 14:51:07 +0200 Subject: [PATCH 1/2] Added request cache to media type retrieval in media picker validation. --- .../MediaPicker3PropertyEditor.cs | 24 +++++++++++++++---- ...ataValueReferenceFactoryCollectionTests.cs | 3 ++- .../MediaPicker3ValueEditorValidationTests.cs | 3 ++- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs index ae43c493efaf..2f8c4f38d6cc 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs @@ -82,7 +82,8 @@ public MediaPicker3PropertyValueEditor( IDataTypeConfigurationCache dataTypeReadCache, ILocalizedTextService localizedTextService, IMediaTypeService mediaTypeService, - IMediaNavigationQueryService mediaNavigationQueryService) + IMediaNavigationQueryService mediaNavigationQueryService, + AppCaches appCaches) : base(shortStringHelper, jsonSerializer, ioHelper, attribute) { _jsonSerializer = jsonSerializer; @@ -95,7 +96,7 @@ public MediaPicker3PropertyValueEditor( var validators = new TypedJsonValidatorRunner, MediaPicker3Configuration>( jsonSerializer, new MinMaxValidator(localizedTextService), - new AllowedTypeValidator(localizedTextService, mediaTypeService, _mediaService), + new AllowedTypeValidator(localizedTextService, mediaTypeService, _mediaService, appCaches), new StartNodeValidator(localizedTextService, mediaNavigationQueryService)); Validators.Add(validators); @@ -404,15 +405,17 @@ internal sealed class AllowedTypeValidator : ITypedJsonValidator /// Initializes a new instance of the class. /// - public AllowedTypeValidator(ILocalizedTextService localizedTextService, IMediaTypeService mediaTypeService, IMediaService mediaService) + public AllowedTypeValidator(ILocalizedTextService localizedTextService, IMediaTypeService mediaTypeService, IMediaService mediaService, AppCaches appCaches) { _localizedTextService = localizedTextService; _mediaTypeService = mediaTypeService; _mediaService = mediaService; + _appCaches = appCaches; } /// @@ -452,9 +455,20 @@ public IEnumerable Validate( foreach (var typeAlias in distinctTypeAliases) { - IMediaType? type = _mediaTypeService.Get(typeAlias); + // Cache media type lookups since the same media type is likely to be used multiple times in validation, + // particularly if we have multiple languages and blocks. + var cacheKey = $"{nameof(AllowedTypeValidator)}_MediaTypeKey_{typeAlias}"; + Guid? typeKey = _appCaches.RequestCache.GetCacheItem(cacheKey); + if (typeKey is null) + { + typeKey = _mediaTypeService.Get(typeAlias)?.Key; + if (typeKey is not null) + { + _appCaches.RequestCache.Set(cacheKey, typeKey); + } + } - if (type is null || allowedTypes.Contains(type.Key.ToString()) is false) + if (typeKey is null || allowedTypes.Contains(typeKey.ToString()) is false) { return [ diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs index 953301f74f50..a5fed60fec25 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs @@ -41,7 +41,8 @@ public class DataValueReferenceFactoryCollectionTests Mock.Of(), Mock.Of(), Mock.Of(), - Mock.Of())); + Mock.Of(), + AppCaches.Disabled)); private IIOHelper IOHelper { get; } = Mock.Of(); diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/MediaPicker3ValueEditorValidationTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/MediaPicker3ValueEditorValidationTests.cs index 6816b1761504..8bd7f3b18790 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/MediaPicker3ValueEditorValidationTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/MediaPicker3ValueEditorValidationTests.cs @@ -218,7 +218,8 @@ private static (MediaPicker3PropertyEditor.MediaPicker3PropertyValueEditor Value Mock.Of(), Mock.Of(), mediaTypeServiceMock.Object, - mediaNavigationQueryServiceMock.Object) + mediaNavigationQueryServiceMock.Object, + AppCaches.Disabled) { ConfigurationObject = new MediaPicker3Configuration() }; From 1e559c24b498cf336a9eca2478c59f495bb7ed79 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Tue, 7 Oct 2025 15:15:02 +0200 Subject: [PATCH 2/2] Applied suggestions from code review. --- .../PropertyEditors/MediaPicker3PropertyEditor.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs index 2f8c4f38d6cc..26efa02f1029 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs @@ -402,6 +402,8 @@ public IEnumerable Validate( /// internal sealed class AllowedTypeValidator : ITypedJsonValidator, MediaPicker3Configuration> { + private const string MediaTypeCacheKeyFormat = nameof(AllowedTypeValidator) + "_MediaTypeKey_{0}"; + private readonly ILocalizedTextService _localizedTextService; private readonly IMediaTypeService _mediaTypeService; private readonly IMediaService _mediaService; @@ -457,18 +459,18 @@ public IEnumerable Validate( { // Cache media type lookups since the same media type is likely to be used multiple times in validation, // particularly if we have multiple languages and blocks. - var cacheKey = $"{nameof(AllowedTypeValidator)}_MediaTypeKey_{typeAlias}"; - Guid? typeKey = _appCaches.RequestCache.GetCacheItem(cacheKey); + var cacheKey = string.Format(MediaTypeCacheKeyFormat, typeAlias); + string? typeKey = _appCaches.RequestCache.GetCacheItem(cacheKey); if (typeKey is null) { - typeKey = _mediaTypeService.Get(typeAlias)?.Key; + typeKey = _mediaTypeService.Get(typeAlias)?.Key.ToString(); if (typeKey is not null) { _appCaches.RequestCache.Set(cacheKey, typeKey); } } - if (typeKey is null || allowedTypes.Contains(typeKey.ToString()) is false) + if (typeKey is null || allowedTypes.Contains(typeKey) is false) { return [