Im using dotnet core 3.1.403, and developing an api.
Here, seems to be working: ASP.NET Core custom validation attribute localization
https://blogs.msdn.microsoft.com/mvpawardprogram/2017/01/03/asp-net-core-mvc/
https://github.com/aspnet/Mvc/issues/5282
My Adapter Provider
public class CustomValidatiomAttributeAdapterProvider : IValidationAttributeAdapterProvider
{
private readonly IValidationAttributeAdapterProvider _baseProvider =
new ValidationAttributeAdapterProvider();
public IAttributeAdapter GetAttributeAdapter(ValidationAttribute attribute,
IStringLocalizer stringLocalizer)
{
if (attribute is DateTimeAttribute dateTimeAttribute) {
return new DateTimeAttributeAdapter(dateTimeAttribute, stringLocalizer);
}
else
{
return _baseProvider.GetAttributeAdapter(attribute, stringLocalizer);
}
}
}
My Adapter
public class DateTimeAttributeAdapter : AttributeAdapterBase<DateTimeAttribute>
{
public DateTimeAttributeAdapter(DateTimeAttribute attribute, IStringLocalizer
stringLocalizer) : base(attribute, stringLocalizer)
{
}
public override void AddValidation(ClientModelValidationContext context)
{
}
public override string GetErrorMessage(ModelValidationContextBase validationContext)
{
var metadata = validationContext.ModelMetadata;
return GetErrorMessage(metadata, metadata.GetDisplayName());
}
}
My Attribute
public class DateTimeAttribute : ValidationAttribute
{
public DateTimeAttribute() : base(() => "{0} é uma data inválida")
{
}
protected override ValidationResult IsValid(object value, ValidationContext
validationContext)
{
DateTime dateTime;
bool success = DateTime.TryParseExact(
(value as string).Trim(),
new string[] {
"yyyy'-'MM'-'dd' 'HH':'mm':'ss",
"yyyy'-'MM'-'dd'T'HH':'mm':'ss",
"yyyy'-'MM'-'dd",
},
DateTimeFormatInfo.InvariantInfo,
DateTimeStyles.RoundtripKind,
out dateTime
);
if (!success)
{
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
return ValidationResult.Success;
}
}
Here is my Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddLocalization(opt => {
opt.ResourcesPath = "Resources";
});
services.AddControllers()
.AddDataAnnotationsLocalization(opt => {
opt.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(SharedResources));
});
services.AddSingleton<IValidationAttributeAdapterProvider, CustomValidatiomAttributeAdapterProvider>();
}
But, the GetAttributeAdapter method is never called. What is wrong here?
UPDATE
The problem is solved BY NOT calling the base constructor on ValidationAttribute. See Brando Zhang Answer
Instead of:
public DateTimeAttribute() : base(() => "{0} é uma data
inválida")
{
}
I do:
public DateTimeAttribute() : base()
{
ErrorMessage = "{0} is an invalid";
}