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; }
user169867
la source
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.

Jacob
la source
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.

Jordan
la source
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; }
user169867
la source
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.

Nicolai Schlenzig
la source
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.

John Farrell
la source
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 });
        }
    }
}
Erikas Pliauksta
la source
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.")]
David T. Macknet
la source
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

Abi
la source
1

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

Sohail Akhter
la source
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.

Dr Herbie
la source
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