How to provide localized validation messages for validation attributes

前端 未结 4 603
北海茫月
北海茫月 2020-12-09 21:46

I am working on an ASP.NET Core application and I would like to override the default validation error messages for data-annotations, like Required,

4条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-09 22:07

    For those that end up here, in search of a general solution, the best way to solve it is using a Validation Metadata Provider. I based my solution on this article: AspNetCore MVC Error Message, I usted the .net framework style localization, and simplified it to use the designed provider.

    1. Add a Resource file for example ValidationsMessages.resx to your project, and set the Access Modifier as Internal or Public, so that the code behind is generated, that will provide you with the ResourceManager static instance.
    2. Add a custom localization for each language ValidationsMessages.es.resx. Remember NOT to set Access Modifier for this files, the code is created on step 1.
    3. Add an implementation of IValidationMetadataProvider
    4. Add the localizations based on the Attributes Type Name like "RequiredAtrribute".
    5. Setup your app on the Startup file.

    Sample ValidationsMessages.es.resx

    Sample for IValidatioMetadaProvider:

    using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
    using System.ComponentModel.DataAnnotations;
    using System.Reflection;
    
    public class LocalizedValidationMetadataProvider : IValidationMetadataProvider
    {
        public LocalizedValidationMetadataProvider()
        {
        }
    
        public void CreateValidationMetadata(ValidationMetadataProviderContext context)
        {
            if (context.Key.ModelType.GetTypeInfo().IsValueType && Nullable.GetUnderlyingType(context.Key.ModelType.GetTypeInfo()) == null && context.ValidationMetadata.ValidatorMetadata.Where(m => m.GetType() == typeof(RequiredAttribute)).Count() == 0)
                context.ValidationMetadata.ValidatorMetadata.Add(new RequiredAttribute());
            foreach (var attribute in context.ValidationMetadata.ValidatorMetadata)
            {
                var tAttr = attribute as ValidationAttribute;
                if (tAttr?.ErrorMessage == null && tAttr?.ErrorMessageResourceName == null)
                {
                    var name = tAttr.GetType().Name;
                    if (Resources.ValidationsMessages.ResourceManager.GetString(name) != null)
                    {
                        tAttr.ErrorMessageResourceType = typeof(Resources.ValidationsMessages);
                        tAttr.ErrorMessageResourceName = name;
                        tAttr.ErrorMessage = null;
                    }
                }
            }
        }
    }
    

    Add the provider to the ConfigureServices method on the Startup class:

    services.AddMvc(options =>
    {
         options.ModelMetadataDetailsProviders.Add(new LocalizedValidationMetadataProvider());
    })
    

提交回复
热议问题