Как создать пользовательские валидаторы аннотаций данных

Желая создать пользовательскую проверку аннотации данных. Есть ли полезные руководства / образцы о том, как их создать?

Во-первых:
StringLength с минимальной и максимальной длиной. Я знаю, что.NET 4 может сделать это, но хочу сделать то же самое в.NET 3.5, если возможно, имея возможность определять только минимальную длину (как минимум x символов), только максимальную длину (до x символов) или оба (между x и y символами).

Во-вторых:
Валидация с использованием арифметики модуля - если число является допустимой длиной, я хочу проверить с использованием алгоритма Modulus 11 (я уже реализовал его в JavaScript, поэтому я предполагаю, что это будет просто перенос?)

Обновить:
Решил вторую проблему - просто скопировал реализацию JavaScript и внес несколько изменений, поэтому решение для этого не нужно.

3 ответа

Решение

Чтобы создать пользовательский валидатор аннотаций данных, следуйте этим рекомендациям:

  1. Ваш класс должен наследовать от System.ComponentModel.DataAnnotations.ValidationAttribute учебный класс.
  2. Override bool IsValid(object value) метод и реализовать логику проверки внутри него.

Вот и все.

ВАЖНО Внимание

Иногда разработчики проверяют, что значение не равно нулю / пусто, и возвращают false. Это обычно некорректное поведение, потому что это на Required валидатор, чтобы проверить, что означает, что ваши пользовательские валидаторы должны только проверять ненулевые данные, но возвращать true в противном случае (см. пример). Это сделает их пригодными для использования в обязательных (обязательных) и необязательных полях.

пример

public class StringLengthRangeAttribute : ValidationAttribute
{
    public int Minimum { get; set; }
    public int Maximum { get; set; }

    public StringLengthRangeAttribute()
    {
        this.Minimum = 0;
        this.Maximum = int.MaxValue;
    }

    public override bool IsValid(object value)
    {
        string strValue = value as string;
        if (!string.IsNullOrEmpty(strValue))
        {
            int len = strValue.Length;
            return len >= this.Minimum && len <= this.Maximum;
        }
        return true;
    }
}

Все свойства могут быть установлены в атрибуте, как вы хотите их установить.
Некоторые примеры:

[Required]
[StringLengthRange(Minimum = 10, ErrorMessage = "Must be >10 characters.")]

[StringLengthRange(Maximum = 20)]

[Required]
[StringLengthRange(Minimum = 10, Maximum = 20)]

Когда конкретное свойство не установлено, его значение устанавливается в конструкторе, поэтому оно всегда имеет значение. В приведенных выше примерах использования я намеренно добавил Required валидатор, так что он синхронизирован с вышеупомянутым предостережением, которое я написал.

Важный

Таким образом, этот валидатор все равно будет работать со значением вашей модели, которое не требуется, но когда оно присутствует, оно проверяется (представьте текстовое поле в веб-форме, это не обязательно, но если пользователь вводит значение в, оно должно быть действительным),

Использовать CustomValidationAttribute вместе с функцией проверки с подписью

public static ValidationResult Validate(MyType x, ValidationContext context)

Пример (для строкового свойства)

using System.ComponentModel.DataAnnotations;

public class MyClass
{
    [CustomValidation(typeof(MyClass), "Validate")]
    public string MyProperty { get; set; }

    public static ValidationResult Validate(string x, ValidationContext context)
    {
        return (x == "valid")
            ? new ValidationResult(null)
            : ValidationResult.Success;
    }
}

Я знаю, что это действительно старая тема, но у меня возникли проблемы с поиском ответа, который я действительно хотел, пока я не нашел этот ответ: /questions/3622929/obrabotka-validatsii-modelstate-v-aspnet-web-api/55050632#55050632

Напомним, что вам нужно настроить службу при запуске, создав соответствующие объекты, которые обрабатывают ошибку, которую вы хотите вернуть:

      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2).ConfigureApiBehaviorOptions(options =>
        {
            options.InvalidModelStateResponseFactory = (context) =>
            {
                var errors = context.ModelState.Values.SelectMany(x => x.Errors.Select(p => new ErrorModel()
               {
                   ErrorCode = ((int)HttpStatusCode.BadRequest).ToString(CultureInfo.CurrentCulture),
                    ErrorMessage = p.ErrorMessage,
                    ServerErrorMessage = string.Empty
                })).ToList();
                var result = new BaseResponse
                {
                    Error = errors,
                    ResponseCode = (int)HttpStatusCode.BadRequest,
                    ResponseMessage = ResponseMessageConstants.VALIDATIONFAIL,

                };
                return new BadRequestObjectResult(result);
            };
       });
Другие вопросы по тегам