【问题标题】:How to localize standard error messages of validation attributes in ASP.NET Core如何在 ASP.NET Core 中本地化验证属性的标准错误消息
【发布时间】:2020-04-04 15:10:02
【问题描述】:

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

【问题讨论】:

  • 你找到解决办法了吗?

标签: c# asp.net-core-2.2 validationattribute asp.net-core-localization


【解决方案1】:

这在docs 中有详细说明。你可以这样做:

  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));
            });
    }
    

【讨论】:

  • 看起来这种方法需要翻译所有模型中所有属性的 ErrorMessage 参数。我想避免它
【解决方案2】:

如果您只想本地化错误消息而不是构建多语言网站,您可以试试这个:(消息字符串可能是您的语言。)

  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

                })
                ;
        }

见the document of DefaultModelBindingMessageProvider

如果您可以阅读日语,请参阅this article了解更多详情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    相关资源
    最近更新 更多