Как отформатировать сообщение об ошибке из пользовательского валидатора - PullRequest
0 голосов
/ 20 апреля 2020

Я создал собственный валидатор следующим образом:

public class IntArrayRequiredAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        if ((!(value is int[] array) || !array.Any() || array.Any(item => item == 0)))
            return new ValidationResult(this.ErrorMessage);

        return ValidationResult.Success;
    }
}

и применил его к свойству модели:

    [IntArrayRequiredAttribute(ErrorMessage = "You must select {0}.")]
    [Display(Name = "Rol")]
    public int[] Roles { get; set; }

Хорошо, когда проверка не пройдена, эта ошибка отображается:

"You must select {0}."

Как вернуть сообщение об ошибке, чтобы {0} автоматически заменялось отображаемым именем поля, например, встроенными валидаторами?

Ожидаемый результат должен быть "You must select Rol."

РЕДАКТИРОВАТЬ:

Посмотрев исходный код ValidationAttribute, я прочитал:

    public ValidationResult GetValidationResult(object value, ValidationContext validationContext) {
        if (validationContext == null) {
            throw new ArgumentNullException("validationContext");
        }

        ValidationResult result = this.IsValid(value, validationContext);

        // If validation fails, we want to ensure we have a ValidationResult that guarantees it has an ErrorMessage
        if (result != null) {
            bool hasErrorMessage = (result != null) ? !string.IsNullOrEmpty(result.ErrorMessage) : false;
            if (!hasErrorMessage) {
                string errorMessage = this.FormatErrorMessage(validationContext.DisplayName);
                result = new ValidationResult(errorMessage, result.MemberNames);
            }
        }

        return result;
    }

Я увидел, что он вызывает мой переопределенный метод IsValid и это форматирует сообщение. Почему это не форматирование в моем случае?

Если я использую перегрузку IsValid, она форматируется правильно, однако мне нужно использовать этот метод, потому что мне нужен validationContext для других целей проверки.

1 Ответ

0 голосов
/ 21 апреля 2020

Я не думаю, что эталонный источник соответствует реальному коду, как рефлексы:

public ValidationResult GetValidationResult(object value, ValidationContext validationContext)
{
    if (validationContext == null)
    {
        throw new ArgumentNullException("validationContext");
    }
    ValidationResult validationResult = IsValid(value, validationContext);
    if (validationResult != null && (validationResult == null || string.IsNullOrEmpty(validationResult.ErrorMessage)))
    {
        string errorMessage = FormatErrorMessage(validationContext.DisplayName);
        validationResult = new ValidationResult(errorMessage, validationResult.MemberNames);
    }
    return validationResult;
}

Так что, если вы хотите поместить все в одну перегрузку

protected override ValidationResult IsValid(object value, ValidationContext validationContext) {...}

, вы мог позволить базовому классу выполнить форматирование ErrorMessage:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    if ((!(value is int[] array) || !array.Any() || array.Any(item => item == 0)))
    {
       return new ValidationResult(null);
    }

    return ValidationResult.Success;
}

или вы можете выполнить форматирование самостоятельно:

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    if ((!(value is int[] array) || !array.Any() || array.Any(item => item == 0)))
    {
        string errorMessage = FormatErrorMessage(validationContext.DisplayName);
        return new ValidationResult(errorMessage);
    }

    return ValidationResult.Success;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...