ASP.NET Core custom validation attribute localization

后端 未结 3 651
面向向阳花
面向向阳花 2020-12-14 20:22

I\'m trying to implement localization in a custom validation attribute in asp.net core 1.0. This is my simplified viewmodel:

public class EditPasswordViewMod         


        
相关标签:
3条回答
  • 2020-12-14 20:44

    The answer from Ramin is the correct answer. But I decided to take another path, so I don't have to write adapters and adapter providers for many cases.

    The idea is to wrap your specific string localizer in a service interface, and get it from the validation attribute itself.

    public class CPFAttribute: ValidationAttribute
    {
        public CPFAttribute()
        {
        }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            string cpf;
    
            try
            {
                cpf = (string)value;
            }
            catch (Exception)
            {
                return new ValidationResult(GetErrorMessage(validationContext));
            }
    
            if (string.IsNullOrEmpty(cpf) || cpf.Length != 11 || !StringUtil.IsDigitsOnly(cpf))
            {
                return new ValidationResult(GetErrorMessage(validationContext));
            }
    
            return ValidationResult.Success;
        }
    
        private string GetErrorMessage(ValidationContext validationContext)
        {
            if (string.IsNullOrEmpty(ErrorMessage))
            {
                return "Invalid CPF";
            }
    
            ErrorMessageTranslationService errorTranslation = validationContext.GetService(typeof(ErrorMessageTranslationService)) as ErrorMessageTranslationService;
            return errorTranslation.GetLocalizedError(ErrorMessage);
        }
    }
    
    

    Then the service can be created as:

    public class ErrorMessageTranslationService
    {
        private readonly IStringLocalizer<SharedResource> _sharedLocalizer;
        public ErrorMessageTranslationService(IStringLocalizer<SharedResource> sharedLocalizer)
        {
            _sharedLocalizer = sharedLocalizer;
        }
    
        public string GetLocalizedError(string errorKey)
        {
            return _sharedLocalizer[errorKey];
        }
    }
    

    The service can be registered as a singleton, in the Startup class.

    services.AddSingleton<ErrorMessageTranslationService>();
    

    If these validation attributes need to be factored to another assembly, just create an interface for this translation service that can be referenced by all validation attributes you create.

    0 讨论(0)
  • 2020-12-14 20:44

    You need to specify the culture. What does formaterrormesage will do? Will it handle the culture?

    Check this link

    0 讨论(0)
  • 2020-12-14 20:58

    Implement an adapter for localization:

    public class RequiredIfAttributeAdapter : AttributeAdapterBase<RequiredIfAttribute>
    {
        public RequiredIfAttributeAdapter(RequiredIfAttribute attribute, IStringLocalizer stringLocalizer) : base(attribute, stringLocalizer) {}
    
        public override void AddValidation(ClientModelValidationContext context) {}
    
        public override string GetErrorMessage(ModelValidationContextBase validationContext)
        {
            return GetErrorMessage(validationContext.ModelMetadata, validationContext.ModelMetadata.GetDisplayName());
        }
    }
    

    Implement a provider for the adapter(s):

    public class CustomValidationAttributeAdapterProvider : IValidationAttributeAdapterProvider
    {
        private readonly IValidationAttributeAdapterProvider _baseProvider = new ValidationAttributeAdapterProvider();
    
        public IAttributeAdapter GetAttributeAdapter(ValidationAttribute attribute, IStringLocalizer stringLocalizer)
        {
            if (attribute is RequiredIfAttribute)
                return new RequiredIfAttributeAdapter(attribute as RequiredIfAttribute, stringLocalizer);
            else
                return _baseProvider.GetAttributeAdapter(attribute, stringLocalizer);
        }
    }
    

    Register the provider in Startup.cs:

    services.AddSingleton<IValidationAttributeAdapterProvider, CustomValidationAttributeAdapterProvider>();
    

    Credits to this blog: https://blogs.msdn.microsoft.com/mvpawardprogram/2017/01/03/asp-net-core-mvc/

    0 讨论(0)
提交回复
热议问题