How to translate "Errormessage" from a "Custom Attribute"

Asked

Viewed 420 times

4

I created a Custom Attribute which is valid only if a property CPF is a valid CPF, but when locating the application I noticed that my Custom Attribute were not having their messages located by the Framework as opposed to Data Attribute Required that has your message located correctly:

Example of the use of attributes being that Required is correctly located

[Required(ErrorMessage = "CPF Requerido")]
[CPF(ErrorMessage = "CPF Inválido")]
public string CPF { get; set; }

Setting location in Startup.Cs file

services
    .AddMvc()
    .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
    .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
    .AddDataAnnotationsLocalization(options =>
    {
        options.DataAnnotationLocalizerProvider = (type, factory) =>
        {
             return factory.Create(typeof(SharedResource));
        };
    });

Custom validation class:

public class CPFAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        //Omitido por não fazer parte do context
    }
}

Versions:

Microsoft.AspNetCore.App (2.1.1)

Microsoft.NETCore.App (2.1)

Example in English:

Exemplo em inglês

Example in Portuguese:

Exemplo em português

1 answer

2


You need to add the settings in the constructor, or in the attribute configuration, in the constructor:

//base.ErrorMessageResourceName = "/*nome da chave*/" ou
base.ErrorMessageResourceType = typeof(/*ResourceName*/);

or in the attribute:

[CPFAttribute(ErrorMessageResourceType = typeof(/*ResourceName*/).

This part is only the server validation, you need to send the message with ValidationResult(ErrorMessage) which is what you typed in the configuration ErrorMessage, example:

public class CPFAttribute : ValidationAttribute, IClientModelValidator
{
    public CPFAttribute()
    {
        base.ErrorMessageResourceName = "/*nome da chave*/"
        base.ErrorMessageResourceType = typeof(/*ResourceName*/);
    }
    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        if (cpf for válido) //se for válido
        {
             return ValidationResult.Success;
        }   
        //se for inválido passe o valor da mensagem
        return new ValidationResult(ErrorMessage);
    }
    public void AddValidation(ClientModelValidationContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }
        context.Attributes.Add("data-val","true");
        context.Attributes.Add("data-val-cpf", 
                 !string.IsNullOrEmpty(ErrorMessage)) 
                 ? ErrorMessage 
                 : "CPF invalid");
    }
}

I also went a little further and put the implementation of the client side part that now needs to also create the function on jQuery.Validation to work as well:

(function ($) {
    $.validator.addMethod('data-val-cpf',
        function (value, element, params) {                        
            cpf = value.replace(/[^\d]+/g,'');  
            if(cpf == '') return false;                 
            if (cpf.length != 11 || 
                cpf == "00000000000" || 
                cpf == "11111111111" || 
                cpf == "22222222222" || 
                cpf == "33333333333" || 
                cpf == "44444444444" || 
                cpf == "55555555555" || 
                cpf == "66666666666" || 
                cpf == "77777777777" || 
                cpf == "88888888888" || 
                cpf == "99999999999")
                    return false;       
            // Valida 1o digito 
            add = 0;    
            for (i=0; i < 9; i ++)      
                add += parseInt(cpf.charAt(i)) * (10 - i);  
                rev = 11 - (add % 11);  
                if (rev == 10 || rev == 11)     
                    rev = 0;    
                if (rev != parseInt(cpf.charAt(9)))     
                    return false;       
            // Valida 2o digito 
            add = 0;    
            for (i = 0; i < 10; i ++)       
                add += parseInt(cpf.charAt(i)) * (11 - i);  
            rev = 11 - (add % 11);  
            if (rev == 10 || rev == 11) 
                rev = 0;    
            if (rev != parseInt(cpf.charAt(10)))
                return false;       
            return true;
        }, function (params, element) {            
            var msgCompare = $(element).attr('data-val-cpf');
            if (!msgCompare) {
                msgCompare = 'CPF inválido';
            }
            return msgCompare;
        });
    $.validator.unobtrusive.adapters.addBool('data-val-cpf');
})(jQuery);

this way you have the two validations with the messages you configured in the code.

Ref. C# using Resource file for validation messages

  • So Virgilio, thank you for your reply but I believe that the point you addressed does not cover the location, today is already shown to Errormessage of Cpfattribute, however this message is not located as well as that of Required (which is a "standard Annotation")

  • 1

    You can explain better in your question @Ricardo passing examples?

  • 1

    I added an example in Portuguese and English

  • Does he keep appearing only in English? @Ricardo ???

  • Appears only in English "Invalid CPF"

  • 1

    I have no way to test but, when I get home I do @Ricardo takes a look I think this solves, because, need to inform to the custom attribute what it needs to do ...

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.