Как локализовать стандартные сообщения об ошибках атрибутов проверки в ASP.NET Core (v2.2)? Например, атрибут [Required] имеет следующее сообщение об ошибке "Поле xxx обязательно."; [EmailAddress] имеет "Поле xxx не является действительным адресом электронной почты."; [Сравнить] содержит "'xxx' и 'yyy' не совпадают" и т. д. В нашем проекте мы используем не английский язык, и я хочу найти способ, как переводить стандартные сообщения об ошибках, не записывая их напрямую в каждый атрибут каждого класса модели данных.
Как локализовать стандартные сообщения об ошибках атрибутов проверки в ASP.NET Core
comment
Вы нашли какое-нибудь решение?
- person user3172616   schedule 24.12.2020
Ответы (2)
Это указано в документы. Вы можете сделать либо:
Используйте опцию
ResourcePath
для атрибута.[Required(ResourcePath = "Resources")]
Затем вы добавите локализованное сообщение в
Resources/Namespace.To.MyClass.[lang].resx
.Используйте один файл ресурсов для всех классов:
public void ConfigureServices(IServiceCollection services) { services.AddMvc() .AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(SharedResource)); }); }
person
Chris Pratt
schedule
11.12.2019
похоже, что этот подход предполагает перевод параметра ErrorMessage для всех атрибутов во всех моделях. Я хочу избежать этого
- person Vitaliy; 12.12.2019
Если вы просто хотите локализовать сообщения об ошибках, а не создавать многоязычный сайт, вы можете попробовать следующее: (строки сообщений могут быть на вашем языке.)
- Добавьте пользовательский
IValidationMetadataProvider
:
public class MyModelMetadataProvider : IValidationMetadataProvider
{
public void CreateValidationMetadata(ValidationMetadataProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException();
}
var validators = context.ValidationMetadata.ValidatorMetadata;
// add [Required] for value-types (int/DateTime etc)
// to set ErrorMessage before asp.net does it
var theType = context.Key.ModelType;
var underlyingType = Nullable.GetUnderlyingType(theType);
if (theType.IsValueType &&
underlyingType == null && // not nullable type
validators.Where(m => m.GetType() == typeof(RequiredAttribute)).Count() == 0)
{
validators.Add(new RequiredAttribute());
}
foreach (var obj in validators)
{
if (!(obj is ValidationAttribute attribute))
{
continue;
}
fillErrorMessage<RequiredAttribute>(attribute,
"You must fill in '{0}'.");
fillErrorMessage<MinLengthAttribute>(attribute,
"Min length of '{0}' is {1}.");
fillErrorMessage<MaxLengthAttribute>(attribute,
"Max length of '{0}' is {1}.");
fillErrorMessage<EmailAddressAttribute>(attribute,
"Invalid email address.", true);
// other attributes like RangeAttribute, CompareAttribute, etc
}
}
private void fillErrorMessage<T>(object attribute, string errorMessage,
bool forceOverriding = false)
where T : ValidationAttribute
{
if (attribute is T validationAttribute)
{
if (forceOverriding ||
(validationAttribute.ErrorMessage == null
&& validationAttribute.ErrorMessageResourceName == null))
{
validationAttribute.ErrorMessage = errorMessage;
}
}
}
}
- добавьте несколько строк в
Startup.cs
:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews()
.AddMvcOptions(m => {
m.ModelMetadataDetailsProviders.Add(new MyModelMetadataProvider());
m.ModelBindingMessageProvider.SetValueMustBeANumberAccessor(
fieldName => string.Format("'{0}' must be a valid number.", fieldName));
// you may check the document of `DefaultModelBindingMessageProvider`
// and add more if needed
})
;
}
см. документ DefaultModelBindingMessageProvider
Если вы умеете читать на японском, см. эту статью для более подробной информации.
person
percyboy
schedule
18.02.2021