Как указать минимальное, но не максимальное десятичное число, используя атрибут аннотации данных диапазона?


150

Я хотел бы указать, что десятичное поле для цены должно быть> = 0, но я не хочу навязывать максимальное значение.

Вот что у меня есть ... Я не уверен, как правильно это сделать.

[Range(typeof(decimal), "0", "??"] public decimal Price { get; set; }

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

Ответы:


226

Как насчет чего-то вроде этого:

[Range(0.0, Double.MaxValue, ErrorMessage = "The field {0} must be greater than {1}.")]

Это должно делать то, что вы ищете, и вы можете избежать использования строк.


1
Я использовал его для Int32 (Int32.MaxValue), и все в порядке, спасибо!
— Бронек

15
Это действительно показывает глупое сообщение проверки :(The field Fixed price discount must be between 0.01 and 1.79769313486232E+308.
— Петр Кула

16
@ppumkin Använd ErrorMessage, то есть [Range (0.0, Double.MaxValue, ErrorMessage = "ваша ошибка здесь")]
— flafffl

Спасибо Джейкоб. Отличный ответ!
— pimbrouwers

1
@ppumkin наследуют от класса DataAnnotationsModelValidator для настройки сообщений об ошибках
— Александр

91

Если вы обеспокоены тем, что строка выглядит красиво, вы можете сделать это:

    [Range(0, Double.PositiveInfinity)]

Это будет иметь сообщение об ошибке по умолчанию:

Поле SuchAndSuch должно быть от 0 до бесконечности.


11
Это лучший ответ здесь ИМХО, без расширений, без, казалось бы, случайных строк / чисел, без специального кода и достаточно разумного сообщения об ошибке.
— Витани

42

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

[Range(typeof(decimal), "0", "79228162514264337593543950335")]
public decimal Price { get; set; }

14
Этот код выглядит просто ужасно. Я бы предложил использовать dataannotationsextensions.org через nuget и, как ответил @Nicolai Schlenzig. Использовать [Min(0)]- это также имеет лучшее сообщение проверки. Я бы предложил обновить ваш ответ
— Петр Кула

Я обновил его, чтобы сделать его таким же, как лучший ответ здесь, так как ОП не меняет своего мнения, лол
— Worthy7

Ответы выше (@Jordan и @Jacob) гораздо более уместны. Тем более что речь идет о цене. Я понимаю, что во многих случаях транзакции должны выполняться с десятичными значениями, но нет цены в 1,234 доллара или, по крайней мере, в большинстве случаев вы не хотите показывать это пользователю.
— Анастасиос Сельманис

@AnastasiosSelmanis, я согласен с вами, ожидайте, когда вы скажете: «Но цена не равна 1,234 доллара». Вы принимаете доллары США, и даже тогда, когда вы используете это для обмена валют (хотя это не упоминается здесь ОП), доллары США идут в большем количестве десятичных знаков. =)
— RoLYroLLs

35

Ты можешь использовать:

[Min(0)]

Это наложит обязательное минимальное значение 0 (ноль), а не максимальное значение.

Вам нужны DataAnnotationsExtensions, чтобы использовать это.


8
Нет, я не думаю, что это правильно. Он не является частью стандартной инфраструктуры MVC3, он взят из расширений аннотаций данных dataannotationsextensions.org . Пожалуйста, предоставьте ссылку MSDN.
— Берни Уайт

1
НЕТ - определенно НЕ является частью MVC 3 :( Но эта библиотека - хорошее расширение, чтобы иметь какое-либо значение :)
— Петр Кула

1
Не является частью MVC3, но это не важно. Если вы хотите проверить на стороне клиента, вам просто нужно использовать пакет DataAnnotationsExtensions.MVC3. Эти два пакета доступны на nuget. Я думаю, что это лучший подход, так как у вас нет глупого сообщения об ошибке или вам не нужно переопределять сообщение об ошибке каждый раз, когда вы хотите проверить положительное целое или десятичное число (что довольно часто встречается).
— горечавка

21

Если вы работаете с ценами, я уверен, вы можете с уверенностью предположить, что ничего не будет стоить более 1 триллиона долларов.

Я бы использовал:

[Range(0.0, 1000000000000)]

Или, если вам это действительно нужно, просто вставьте значение Decimal.MaxValue(без запятых):79,228,162,514,264,337,593,543,950,335

Любой из них будет хорошо работать, если вы не из Зимбабве.


7
Почему не просто [Range(0.0,Decimal.MaxValue)]?
— Курятник

4
Не компилируется, Decimal.MaxValue не является константой.
— Джон Фаррелл,

Эта константа - неприятность, ссылаться на файл ресурсов для текста ошибки не легче
— Coops

3
Теперь вы делаете предположение, что валютой является доллар, а не йена или что-то еще.
— Фред

1
@jfar Decimal.MaxValue - это константа. Просто у Range нет перегрузки для размещения десятичной дроби.
— Ε Г И І И О

11

Вы можете использовать пользовательскую проверку:

    [CustomValidation(typeof(ValidationMethods), "ValidateGreaterOrEqualToZero")]
    public int IntValue { get; set; }

    [CustomValidation(typeof(ValidationMethods), "ValidateGreaterOrEqualToZero")]
    public decimal DecValue { get; set; }

Тип методов проверки:

public class ValidationMethods
{
    public static ValidationResult ValidateGreaterOrEqualToZero(decimal value, ValidationContext context)
    {
        bool isValid = true;

        if (value < decimal.Zero)
        {
            isValid = false;
        }

        if (isValid)
        {
            return ValidationResult.Success;
        }
        else
        {
            return new ValidationResult(
                string.Format("The field {0} must be greater than or equal to 0.", context.MemberName),
                new List<string>() { context.MemberName });
        }
    }
}

2

Я собирался попробовать что-то вроде этого:

[Range(typeof(decimal), ((double)0).ToString(), ((double)decimal.MaxValue).ToString(), ErrorMessage = "Amount must be greater than or equal to zero.")]

Однако проблема заключается в том, что компилятору требуется постоянное выражение, что запрещено ((double)0).ToString(). Компилятор будет принимать

[Range(0d, (double)decimal.MaxValue, ErrorMessage = "Amount must be greater than zero.")]

Может ли тот, кто отрицает это, объяснить, почему вы считаете, что мое решение плохое или бесполезное? Потому что простое голосование без объяснения причин совершенно бесполезно.
— Дэвид Т. Макнет

Ваше сообщение об ошибке должно сказать «больше или равно».
— Ε Г И І И О

Хороший улов. Добавлен.
— Дэвид Т. Макнет

1

используя Range с

[Range(typeof(Decimal), "0", "9999", ErrorMessage = "{0} must be a decimal/number between {1} and {2}.")]

[Range(typeof(Decimal),"0.0", "1000000000000000000"]

Надеюсь, это поможет



0

Я бы decimal.MaxValue.ToString()сказал, так как это эффективный потолок для десятичного типа, он эквивалентен отсутствию верхней границы.


4
Проблема в том, что это не константа. Вы получите эту ошибку: Аргументом атрибута должно быть константное выражение, выражение typeof или выражение создания массива типа параметра атрибута
— user169867

Как я указал ниже, но, видимо, это не было оценено кем-то.
— Дэвид Т. Макнет
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.