Comment spécifier une décimale minimale mais pas maximale à l'aide de l'attribut d'annotation de données de plage?


150

Je voudrais préciser qu'un champ décimal pour un prix doit être> = 0 mais je ne veux pas vraiment imposer une valeur max.

Voici ce que j'ai jusqu'à présent ... Je ne sais pas quelle est la bonne façon de procéder.

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

Si cela va dans une base de données, vous devrez certainement spécifier le nombre maximum autorisé en fonction du type de base de données sélectionné? Sinon, vous obtiendrez une mauvaise exception si ce nombre est dépassé
Coops

Réponses:


226

Que diriez-vous quelque chose comme ça:

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

Cela devrait faire ce que vous recherchez et vous pouvez éviter d'utiliser des chaînes.


1
Je l'ai utilisé pour Int32 (Int32.MaxValue) et c'est ok, merci!
Bronek

15
Il affiche cependant un message de validation stupide :(The field Fixed price discount must be between 0.01 and 1.79769313486232E+308.
Piotr Kula

16
@ppumkin Använd ErrorMessage, ie [Range (0.0, Double.MaxValue, ErrorMessage = "your error here")]
flafffl

Merci Jacob. Très bonne réponse!
pimbrouwers

1
@ppumkin hérite de la classe DataAnnotationsModelValidator pour personnaliser les messages d'erreur
Alexander

91

Si vous êtes préoccupé par la belle apparence de la chaîne, vous pouvez le faire:

    [Range(0, Double.PositiveInfinity)]

Cela aura un message d'erreur par défaut de:

Le champ SuchAndSuch doit être compris entre 0 et Infinity.


11
C'est la meilleure réponse ici IMHO, pas d'extensions, pas de chaînes / nombre apparemment aléatoires, pas de code personnalisé et un message d'erreur raisonnablement raisonnable.
Vitani

42

Il semble qu'il n'y ait pas d'autre choix que de mettre manuellement la valeur maximale. J'espérais qu'il y avait un type de surcharge où vous n'aviez pas besoin d'en spécifier une.

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

14
Ce code a l'air horrible. Je suggérerais d'utiliser dataannotationsextensions.org via nuget et comme @Nicolai Schlenzig a répondu. Utilisation [Min(0)]- Cela a également un meilleur message de validation. Je suggérerais de mettre à jour votre réponse
Piotr Kula

Je l'ai mis à jour pour en faire la même chose que la meilleure réponse ici, car l'OP ne change pas d'avis lol
Worthy7

Les réponses ci-dessus (@Jordan et @Jacob) sont beaucoup plus appropriées. D'autant que nous parlons de Price. Je comprends que de nombreuses fois, les transactions doivent être effectuées avec des valeurs décimales, mais il n'y a pas de prix de 1,234 dollars ou du moins la plupart du temps, vous ne voulez pas montrer cela à l'utilisateur.
Anastasios Selmanis

@AnastasiosSelmanis, je suis d'accord avec vous, attendez-vous à la partie quand vous dites "mais il n'y a pas de prix 1.234 dollars". Vous supposez l'USD, et même dans ce cas, lorsque vous l'utilisez pour le change (bien que cela ne soit pas mentionné ici par OP), l'USD entre dans plus de décimales. =)
RoLYroLLs

35

Vous pouvez utiliser:

[Min(0)]

Cela imposera une valeur minimale requise de 0 (zéro) et aucune valeur maximale.

Vous avez besoin de DataAnnotationsExtensions pour l'utiliser.


8
Non, je ne pense pas que ce soit correct. Il ne fait pas partie du framework MVC3 standard, il provient de Data Annotations Extensions dataannotationsextensions.org . Veuillez fournir un lien MSDN.
Bernie White

1
NON - certainement PAS partie de MVC 3 :( BUt cette bibliothèque est une bonne extension à avoir de toute façon :)
Piotr Kula

1
Ne fait pas partie de MVC3 mais ce n'est pas important. Si vous souhaitez une validation côté client, il vous suffit d'utiliser le package DataAnnotationsExtensions.MVC3. Ces deux packages sont disponibles sur nuget. Je pense que c'est la meilleure approche, car vous n'avez pas de message d'erreur stupide ou n'avez pas besoin de redéfinir le message d'erreur à chaque fois que vous souhaitez valider un entier positif ou un décimal (ce qui est assez courant).
gentiane

21

Si vous travaillez avec des prix, je suis sûr que vous pouvez supposer que rien ne coûtera plus de 1 billion de dollars.

J'utiliserais:

[Range(0.0, 1000000000000)]

Ou si vous en avez vraiment besoin, collez simplement la valeur de Decimal.MaxValue(sans les virgules):79,228,162,514,264,337,593,543,950,335

L'un ou l'autre fonctionnera bien si vous n'êtes pas du Zimbabwe.


7
Pourquoi pas juste [Range(0.0,Decimal.MaxValue)]?
Coops

4
Ne compile pas, Decimal.MaxValue n'est pas une constante.
John Farrell

Cette constante est une nuisance, se référer à un fichier de ressources pour le texte d'erreur n'est pas plus facile
Coops

3
Maintenant, vous faites l'hypothèse que la devise est le dollar, pas le yen ou autre chose.
Fred

1
@jfar Decimal.MaxValue EST une constante. C'est juste que la plage n'a pas de surcharge pour accueillir une décimale.
Ε Г И І И О

11

Vous pouvez utiliser la validation personnalisée:

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

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

Type de méthodes de validation:

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

J'allais essayer quelque chose comme ça:

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

Le problème avec cela, cependant, est que le compilateur veut une expression constante, ce qui interdit ((double)0).ToString(). Le compilateur va prendre

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

Est-ce que celui qui a voté contre cela pourrait expliquer pourquoi vous pensez que ma solution est mauvaise ou inutile? Parce que le simple vote négatif sans aucune explication est totalement inutile.
David T.Macknet

Votre message d'erreur doit indiquer "supérieur ou égal à".
Ε Г И І И О

Bonne prise. Ajoutée.
David T.Macknet

1

utilisation de Range avec

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

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

J'espère que cela aidera


1

[Range (0.01,100000000, ErrorMessage = "Le prix doit être supérieur à zéro!")]


0

Je dirais que decimal.MaxValue.ToString()puisque c'est le plafond effectif pour le type decmial, cela équivaut à ne pas avoir de limite supérieure.


4
Le problème est que ce n'est pas une constante. Vous obtiendrez cette erreur: un argument d'attribut doit être une expression constante, une expression de type ou une expression de création de tableau d'un type de paramètre d'attribut
user169867

Comme je l'ai souligné ci-dessous, mais apparemment, personne n'a apprécié.
David T.Macknet
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.