自定义ValidationAttribute不返回本地化的ErrorMessage

时间:2019-10-22 12:55:37

标签: c# .net asp.net-core

我有一个SharedResource文件,该文件的属性已翻译成4种语言。如果iban输入无效,我想返回本地化的ErrorMessage。

本地化仅适用于RequiredAttribute(从ValidationAttribute派生),而不适用于Ibanvalidator。

我在这里做错了什么?

模型

    [LocalizedDisplayName("RegisterFinancialStepViewModel_Iban_DisplayName", typeof(SharedResource))]
    [IbanValidation("ErrorMessage_Invalid_Iban")]
    [StringLength(50)]
    public string Iban { get; set; }

这也不起作用

    [IbanValidation(ErrorMessage = "ErrorMessage_Invalid_Iban")]

IbanValidator类

    public static class IbanValidator
{
    public static bool Validate(string iban)
    {
        return string.IsNullOrEmpty(iban) || ValidateChecksum(iban.ToUpper());
    }

    private static bool ValidateChecksum(string iban)
    {
        if (iban.Length < 4 || iban[0] == ' ' || iban[1] == ' ' || iban[2] == ' ' || iban[3] == ' ')
            return false;

        var checksum = 0;
        var ibanLength = iban.Length;

        for (var charIndex = 0; charIndex < ibanLength; charIndex++)
        {
            if (iban[charIndex] == ' ') continue;

            int value;
            var c = iban[(charIndex + 4) % ibanLength];
            if (c >= '0' && c <= '9')
            {
                value = c - '0';
            }
            else if (c >= 'A' && c <= 'Z')
            {
                value = c - 'A';
                checksum = (checksum * 10 + value / 10 + 1) % 97;
                value %= 10;
            }
            else if (c >= 'a' && c <= 'z')
            {
                value = c - 'a';
                checksum = (checksum * 10 + value / 10 + 1) % 97;
                value %= 10;
            }
            else
            {
                return false;
            }

            checksum = (checksum * 10 + value) % 97;
        }

        return checksum == 1;
    }
}

public class IbanValidationAttribute : ValidationAttribute
{
    private readonly string _errorMessage;

    public IbanValidationAttribute(string errorMessage)
    {
        _errorMessage = errorMessage;
    }
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        return IbanValidator.Validate(value as string)
            ? ValidationResult.Success
            : new ValidationResult(_errorMessage);
    }
}

将IbanValidator替换为Required可以进行本地化,但无法进行验证

    [Required(ErrorMessage = "ErrorMessage_Invalid_Iban")]

1 个答案:

答案 0 :(得分:1)

您可以创建一个ErrorMessageTranslationService来手动定位错误消息。

public class ErrorMessageTranslationService
{
    private readonly IStringLocalizer<SharedResource> _sharedLocalizer;
    public ErrorMessageTranslationService(IStringLocalizer<SharedResource> sharedLocalizer)
    {
        _sharedLocalizer = sharedLocalizer;
    }

    public string GetLocalizedError(string errorKey)
    {
        return _sharedLocalizer[errorKey];
    }
}

并在启动ConfigureServices中注册它:

services.AddSingleton<ErrorMessageTranslationService>();

然后使用您的自定义IbanValidationAttribute

调用服务
public class IbanValidationAttribute : ValidationAttribute
{
    private readonly string _errorMessage;

    public IbanValidationAttribute(string errorMessage)
    {
        _errorMessage = errorMessage;
    }
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        ErrorMessageTranslationService errorTranslation = validationContext.GetService(typeof(ErrorMessageTranslationService)) as ErrorMessageTranslationService;

        return IbanValidator.Validate(value as string)
            ? ValidationResult.Success
            : new ValidationResult(errorTranslation.GetLocalizedError(_errorMessage));
    }
}

型号:

[IbanValidation("ErrorMessage_Invalid_Iban")]
[StringLength(50)]
public string Iban { get; set; }