diff --git a/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs
index 592b2dc2c7..e8866622b8 100644
--- a/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs
+++ b/src/Umbraco.Core/PropertyEditors/Validators/EmailValidator.cs
@@ -1,24 +1,45 @@
using System.ComponentModel.DataAnnotations;
+using Microsoft.Extensions.DependencyInjection;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models.Validation;
+using Umbraco.Cms.Core.Services;
+using Umbraco.Extensions;
namespace Umbraco.Cms.Core.PropertyEditors.Validators;
///
-/// A validator that validates an email address
+/// A validator that validates an email address.
///
public sealed class EmailValidator : IValueValidator
{
+ private readonly ILocalizedTextService _localizedTextService;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 17.")]
+ public EmailValidator()
+ : this(StaticServiceProvider.Instance.GetRequiredService())
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public EmailValidator(ILocalizedTextService localizedTextService) => _localizedTextService = localizedTextService;
+
///
public IEnumerable Validate(object? value, string? valueType, object? dataTypeConfiguration, PropertyValidationContext validationContext)
{
- var asString = value == null ? string.Empty : value.ToString();
+ var valueAsString = value?.ToString() ?? string.Empty;
- var emailVal = new EmailAddressAttribute();
+ var emailAddressAttribute = new EmailAddressAttribute();
- if (asString != string.Empty && emailVal.IsValid(asString) == false)
+ if (valueAsString != string.Empty && emailAddressAttribute.IsValid(valueAsString) == false)
{
- // TODO: localize these!
- yield return new ValidationResult("Email is invalid", new[] { "value" });
+ yield return new ValidationResult(
+ _localizedTextService.Localize("validation", "invalidEmail", [valueAsString]),
+ ["value"]);
}
}
}
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/EmailAddressPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/EmailAddressPropertyEditor.cs
index cbd7ef3a8c..4a2c18b3b5 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/EmailAddressPropertyEditor.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/EmailAddressPropertyEditor.cs
@@ -1,29 +1,50 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
+using Microsoft.Extensions.DependencyInjection;
+using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.PropertyEditors.Validators;
+using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Core.PropertyEditors;
+///
+/// Defines an email address property editor.
+///
[DataEditor(
Constants.PropertyEditors.Aliases.EmailAddress,
ValueEditorIsReusable = true)]
public class EmailAddressPropertyEditor : DataEditor
{
- ///
- /// The constructor will setup the property editor based on the attribute if one is found
- ///
- public EmailAddressPropertyEditor(IDataValueEditorFactory dataValueEditorFactory)
- : base(dataValueEditorFactory)
- => SupportsReadOnly = true;
+ private readonly ILocalizedTextService _localizedTextService;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ [Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 17.")]
+ public EmailAddressPropertyEditor(IDataValueEditorFactory dataValueEditorFactory)
+ : this(
+ dataValueEditorFactory,
+ StaticServiceProvider.Instance.GetRequiredService())
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public EmailAddressPropertyEditor(IDataValueEditorFactory dataValueEditorFactory, ILocalizedTextService localizedTextService)
+ : base(dataValueEditorFactory)
+ {
+ SupportsReadOnly = true;
+ _localizedTextService = localizedTextService;
+ }
+
+ ///
protected override IDataValueEditor CreateValueEditor()
{
IDataValueEditor editor = base.CreateValueEditor();
-
- // add an email address validator
- editor.Validators.Add(new EmailValidator());
+ editor.Validators.Add(new EmailValidator(_localizedTextService));
return editor;
}
}
diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/Validators/EmailValidatorTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/Validators/EmailValidatorTests.cs
new file mode 100644
index 0000000000..24d8bc67a7
--- /dev/null
+++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/Validators/EmailValidatorTests.cs
@@ -0,0 +1,50 @@
+// Copyright (c) Umbraco.
+// See LICENSE for more details.
+
+using System.Globalization;
+using Moq;
+using NUnit.Framework;
+using Umbraco.Cms.Core.Models.Validation;
+using Umbraco.Cms.Core.PropertyEditors;
+using Umbraco.Cms.Core.PropertyEditors.Validators;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.PropertyEditors.Validators;
+
+[TestFixture]
+public class EmailValidatorTests
+{
+ [TestCase(null, true)]
+ [TestCase("", true)]
+ [TestCase(" ", false)]
+ [TestCase("test@test.com", true)]
+ [TestCase("invalid", false)]
+ public void Validates_Email_Address(object? email, bool expectedSuccess)
+ {
+ var validator = CreateValidator();
+ var result = validator.Validate(email, ValueTypes.String, null, PropertyValidationContext.Empty());
+ if (expectedSuccess)
+ {
+ Assert.IsEmpty(result);
+ }
+ else
+ {
+ Assert.AreEqual(1, result.Count());
+
+ var validationResult = result.First();
+ Assert.AreEqual("validation_invalidEmail", validationResult.ErrorMessage);
+ }
+ }
+
+ private static EmailValidator CreateValidator()
+ {
+ var localizedTextServiceMock = new Mock();
+ localizedTextServiceMock.Setup(x => x.Localize(
+ It.IsAny(),
+ It.IsAny(),
+ It.IsAny(),
+ It.IsAny>()))
+ .Returns((string key, string alias, CultureInfo culture, IDictionary args) => $"{key}_{alias}");
+ return new EmailValidator(localizedTextServiceMock.Object);
+ }
+}