Валидаторы мин / макс значений в asp.net mvc

106

Проверка с использованием атрибутов в asp.net mvc действительно хороша. Я использую [Range(min, max)]валидатор до сих пор для проверки значений, например:

[Range(1, 10)]
public int SomeNumber { get; set; }

Однако теперь мне нужно отдельно проверить минимальное и максимальное состояние. Я ожидал найти такие атрибуты:

[MinValue(1, "Value must be at least 1")]
[MaxValue(10, "Value can't be more than 10")]
public int SomeNumber { get; set; }

Есть ли какие-нибудь предопределенные атрибуты для написания этого? Или как мне этого добиться?

stiank81
источник
FluentValidation может быть еще одним решением для определения диапазона дат. Вот мой ответ на другой вопрос, который может оказаться полезным .
Зинов

Ответы:

48

Вот как я бы написал валидатор для MaxValue

public class MaxValueAttribute : ValidationAttribute
    {
        private readonly int _maxValue;

        public MaxValueAttribute(int maxValue)
        {
            _maxValue = maxValue;
        }

        public override bool IsValid(object value)
        {
            return (int) value <= _maxValue;
        }
    }

Атрибут MinValue должен быть примерно таким же

Шарль Уэлле
источник
Хорошо, ожидал, что они существуют, но достаточно справедливо, чтобы их написать. Спасибо!
stiank81
1
Просто, к вашему сведению, это не волшебным образом не подтвердит форму на конце Javascript. Для этого вам нужно будет написать дополнительный код + js.
basarat
3
@basarat на самом деле вам не понадобится дополнительный JS, в библиотеке проверки jquery уже есть функции для min / max, вам просто нужно реализовать IClientValidationинтерфейс с указанным выше атрибутом и вернуть правильные значения из GetClientValidationRulesметода
WickyNilliams
@WickyNilliams, не могли бы вы добавить ответ с примером вашего комментария, или CharlesOuellet, вы отредактируете этот ответ, добавив в него пример комментария Вики? Я хотел бы проголосовать за рабочий пример, который включает проверку на стороне клиента.
Джони Карр
@JohnieKarr Я больше не работаю с .NET, поэтому не могу дать подробного ответа. Тем не менее, этот ответ ниже, кажется, показывает именно то, что я описал
WickyNilliams
195

Я не думаю, что существует атрибут минимальной / максимальной проверки. Я бы использовал что-то вроде

[Range(1, Int32.MaxValue)]

для минимального значения 1 и

[Range(Int32.MinValue, 10)]

для максимального значения 10

Парень
источник
4
Ммм .. Не совсем комфортно с этим. Мне это кажется немного взломанным.
stiank81
21
Это немного взломано ... но иногда хаки заставляют меня чувствовать себя комфортнее :)
Guy
4
Этот подход хорош, если вы переопределите сообщение об ошибке по умолчанию, иначе вы получите что-то ужасное, например: «Свойство x должно быть между -2e ^ 31-1 и 10».
Nine Tails
2
Как это хакерство и неудобно? Мне кажется, это хороший подход.
1
RangeAttributeесть AllowMultiple = false, поэтому он не может скомпилироваться.
Дэниел Шиллинг
38

Полный пример того, как это можно сделать. Чтобы избежать написания сценариев проверки на стороне клиента, был использован существующий ValidationType = "range".

public class MinValueAttribute : ValidationAttribute, IClientValidatable
{
    private readonly double _minValue;

    public MinValueAttribute(double minValue)
    {
        _minValue = minValue;
        ErrorMessage = "Enter a value greater than or equal to " + _minValue;  
    }

    public MinValueAttribute(int minValue)
    {
        _minValue = minValue;
        ErrorMessage = "Enter a value greater than or equal to " + _minValue;
    }

    public override bool IsValid(object value)
    {
        return Convert.ToDouble(value) >= _minValue;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule();
        rule.ErrorMessage = ErrorMessage;
        rule.ValidationParameters.Add("min", _minValue);
        rule.ValidationParameters.Add("max", Double.MaxValue);
        rule.ValidationType = "range";
        yield return rule;
    }

}
Марио
источник
8
Отличный ответ. Я бы немного изменил сообщение об ошибке: «Введите значение больше или равно» - это более (с грамматической точки зрения) правильное сообщение об ошибке.
Tieson T.
0

Плагин jQuery Validation уже реализует минимальные и максимальные правила, нам просто нужно создать адаптер для нашего настраиваемого атрибута:

public class MaxAttribute : ValidationAttribute, IClientValidatable
{
    private readonly int maxValue;

    public MaxAttribute(int maxValue)
    {
        this.maxValue = maxValue;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule();

        rule.ErrorMessage = ErrorMessageString, maxValue;

        rule.ValidationType = "max";
        rule.ValidationParameters.Add("max", maxValue);
        yield return rule;
    }

    public override bool IsValid(object value)
    {
        return (int)value <= maxValue;
    }
}

Адаптер:

$.validator.unobtrusive.adapters.add(
   'max',
   ['max'],
   function (options) {
       options.rules['max'] = parseInt(options.params['max'], 10);
       options.messages['max'] = options.message;
   });

Атрибут Min был бы очень похож.

Бенас Радзявичюс
источник