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


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.