如何本地化 ASP.NET Core 中验证属性的标准错误消息



如何在 ASP.NET 核心(v2.2(中本地化验证属性的标准错误消息?例如,[必需]属性具有此错误消息">xxx 字段是必需的。[电子邮件地址]具有">xxx 字段不是有效的电子邮件地址。[比较]有"'xxx' 和 'yyy' 不匹配">等。在我们的项目中,我们不使用英语,我想找到一种方法来翻译标准错误消息,而无需直接将它们写入每个数据模型类的每个属性中

如果您只想本地化错误消息,而不是构建多语言站点,则可以尝试以下操作:(消息字符串可能使用您的语言。

  1. 添加自定义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;
}
}
}
}
  1. 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

如果您可以用日语阅读,请参阅本文以获取更多详细信息。

这在文档中有详细说明。您可以执行以下任一操作:

  1. 使用属性上的ResourcePath选项。

    [Required(ResourcePath = "Resources")]
    

    然后,您将本地化的消息添加到Resources/Namespace.To.MyClass.[lang].resx.

  2. 对所有类使用一个资源文件:

    public void ConfigureServices(IServiceCollection services)
    {
    services.AddMvc()
    .AddDataAnnotationsLocalization(options => {
    options.DataAnnotationLocalizerProvider = (type, factory) =>
    factory.Create(typeof(SharedResource));
    });
    }
    

最新更新