diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs
index 296e8eed36..1bf19b361b 100644
--- a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs
+++ b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs
@@ -7,7 +7,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators;
///
/// A validator that validates that the value is not null or empty (if it is a string)
///
-public sealed class RequiredValidator : IValueRequiredValidator, IManifestValueValidator
+public class RequiredValidator : IValueRequiredValidator, IManifestValueValidator
{
private const string ValueCannotBeNull = "Value cannot be null";
private const string ValueCannotBeEmpty = "Value cannot be empty";
@@ -23,7 +23,7 @@ public sealed class RequiredValidator : IValueRequiredValidator, IManifestValueV
ValidateRequired(value, valueType);
///
- public IEnumerable ValidateRequired(object? value, string? valueType)
+ public virtual IEnumerable ValidateRequired(object? value, string? valueType)
{
if (value == null)
{
diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs
index 77194cef2e..a9ffc67f64 100644
--- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs
+++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs
@@ -28,6 +28,7 @@ using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Packaging;
using Umbraco.Cms.Core.PropertyEditors;
+using Umbraco.Cms.Core.PropertyEditors.Validators;
using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
using Umbraco.Cms.Core.PublishedCache;
using Umbraco.Cms.Core.Routing;
@@ -238,6 +239,8 @@ public static partial class UmbracoBuilderExtensions
builder.Services.AddSingleton();
+ builder.Services.AddSingleton();
+
return builder;
}
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs
index ee37d8c63b..772e722833 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs
@@ -12,6 +12,7 @@ using Umbraco.Cms.Core.Media;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Blocks;
using Umbraco.Cms.Core.Models.Editors;
+using Umbraco.Cms.Core.PropertyEditors.Validators;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
@@ -166,6 +167,7 @@ public class RichTextPropertyEditor : DataEditor
internal class RichTextPropertyValueEditor : BlockValuePropertyValueEditorBase
{
private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;
+ private readonly ILocalizedTextService _localizedTextService;
private readonly IHtmlSanitizer _htmlSanitizer;
private readonly HtmlImageSourceParser _imageSourceParser;
private readonly HtmlLocalLinkParser _localLinkParser;
@@ -173,8 +175,10 @@ public class RichTextPropertyEditor : DataEditor
private readonly RichTextEditorPastedImages _pastedImages;
private readonly IJsonSerializer _jsonSerializer;
private readonly IBlockEditorElementTypeCache _elementTypeCache;
+ private readonly IRichTextRequiredValidator _richTextRequiredValidator;
private readonly ILogger _logger;
+ [Obsolete("Use non-obsolete constructor. This is schedules for removal in v16.")]
public RichTextPropertyValueEditor(
DataEditorAttribute attribute,
PropertyEditorCollection propertyEditors,
@@ -193,21 +197,66 @@ public class RichTextPropertyEditor : DataEditor
IBlockEditorElementTypeCache elementTypeCache,
IPropertyValidationService propertyValidationService,
DataValueReferenceFactoryCollection dataValueReferenceFactoryCollection)
+ : this(
+ attribute,
+ propertyEditors,
+ dataTypeReadCache,
+ logger,
+ backOfficeSecurityAccessor,
+ localizedTextService,
+ shortStringHelper,
+ imageSourceParser,
+ localLinkParser,
+ pastedImages,
+ jsonSerializer,
+ ioHelper,
+ htmlSanitizer,
+ macroParameterParser,
+ elementTypeCache,
+ propertyValidationService,
+ dataValueReferenceFactoryCollection,
+ StaticServiceProvider.Instance.GetRequiredService())
+ {
+
+ }
+ public RichTextPropertyValueEditor(
+ DataEditorAttribute attribute,
+ PropertyEditorCollection propertyEditors,
+ IDataTypeConfigurationCache dataTypeReadCache,
+ ILogger logger,
+ IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
+ ILocalizedTextService localizedTextService,
+ IShortStringHelper shortStringHelper,
+ HtmlImageSourceParser imageSourceParser,
+ HtmlLocalLinkParser localLinkParser,
+ RichTextEditorPastedImages pastedImages,
+ IJsonSerializer jsonSerializer,
+ IIOHelper ioHelper,
+ IHtmlSanitizer htmlSanitizer,
+ IHtmlMacroParameterParser macroParameterParser,
+ IBlockEditorElementTypeCache elementTypeCache,
+ IPropertyValidationService propertyValidationService,
+ DataValueReferenceFactoryCollection dataValueReferenceFactoryCollection,
+ IRichTextRequiredValidator richTextRequiredValidator)
: base(attribute, propertyEditors, dataTypeReadCache, localizedTextService, logger, shortStringHelper, jsonSerializer, ioHelper, dataValueReferenceFactoryCollection)
{
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
+ _localizedTextService = localizedTextService;
_imageSourceParser = imageSourceParser;
_localLinkParser = localLinkParser;
_pastedImages = pastedImages;
_htmlSanitizer = htmlSanitizer;
_macroParameterParser = macroParameterParser;
_elementTypeCache = elementTypeCache;
+ _richTextRequiredValidator = richTextRequiredValidator;
_jsonSerializer = jsonSerializer;
_logger = logger;
Validators.Add(new RichTextEditorBlockValidator(propertyValidationService, CreateBlockEditorValues(), elementTypeCache, jsonSerializer, logger));
}
+ public override IValueRequiredValidator RequiredValidator => _richTextRequiredValidator;
+
///
public override object? Configuration
{
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/Validators/IRichTextRequiredValidator.cs b/src/Umbraco.Infrastructure/PropertyEditors/Validators/IRichTextRequiredValidator.cs
new file mode 100644
index 0000000000..7358e92f38
--- /dev/null
+++ b/src/Umbraco.Infrastructure/PropertyEditors/Validators/IRichTextRequiredValidator.cs
@@ -0,0 +1,7 @@
+using Umbraco.Cms.Core.PropertyEditors;
+
+namespace Umbraco.Cms.Core.PropertyEditors.Validators;
+
+internal interface IRichTextRequiredValidator : IValueRequiredValidator
+{
+}
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRequiredValidator.cs b/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRequiredValidator.cs
new file mode 100644
index 0000000000..b239f0bda5
--- /dev/null
+++ b/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRequiredValidator.cs
@@ -0,0 +1,30 @@
+using System.ComponentModel.DataAnnotations;
+using Microsoft.Extensions.Logging;
+using Umbraco.Cms.Core.Serialization;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Cms.Core.PropertyEditors.Validators;
+
+internal class RichTextRequiredValidator : RequiredValidator, IRichTextRequiredValidator
+{
+ private readonly IJsonSerializer _jsonSerializer;
+ private readonly ILogger _logger;
+
+ public RichTextRequiredValidator(ILocalizedTextService textService, IJsonSerializer jsonSerializer, ILogger logger) : base(textService)
+ {
+ _jsonSerializer = jsonSerializer;
+ _logger = logger;
+ }
+
+ public override IEnumerable ValidateRequired(object? value, string? valueType) => base.ValidateRequired(GetValue(value), valueType);
+
+ private object? GetValue(object? value)
+ {
+ if(RichTextPropertyEditorHelper.TryParseRichTextEditorValue(value, _jsonSerializer, _logger, out RichTextEditorValue? richTextEditorValue))
+ {
+ return richTextEditorValue?.Markup;
+ }
+
+ return value;
+ }
+}