Validateurs de valeur min / max dans asp.net mvc

106

La validation à l'aide d'attributs dans asp.net mvc est vraiment sympa. J'ai utilisé le [Range(min, max)]validateur jusqu'à présent pour vérifier des valeurs, comme par exemple:

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

Cependant, je dois maintenant vérifier séparément les conditions min et max. Je m'attendais à trouver des attributs comme ceux-ci:

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

Y a-t-il des attributs prédéfinis pour écrire ceci? Ou comment puis-je y parvenir?

stiank81
la source
FluentValidation peut être une autre solution pour résoudre la plage de dates. Voici ma réponse à une autre question qui pourrait être utile .
Zinov

Réponses:

48

Voici comment j'écrirais un validateur pour 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;
        }
    }

L'attribut MinValue doit être sensiblement le même

Charles Ouellet
la source
Ok, je m'attendais à ce qu'ils existent, mais assez juste pour les écrire. THX!
stiank81
1
Juste pour info, cela ne validerait pas comme par magie le formulaire du côté Javascript. Vous auriez besoin d'écrire du code supplémentaire + js pour cela.
basarat
3
@basarat en fait, vous n'aurez pas besoin de JS supplémentaire, la bibliothèque de validation jquery a déjà des fonctions pour min / max, il vous suffit d'implémenter l' IClientValidationinterface sur l'attribut ci-dessus et de renvoyer les valeurs correctes de la GetClientValidationRulesméthode
WickyNilliams
@WickyNilliams ajouteriez-vous une réponse avec un exemple de votre commentaire, ou CharlesOuellet éditerez-vous cette réponse avec un exemple du commentaire de Wicky? J'adorerais voter pour un exemple de travail qui inclut la validation côté client.
Johnie Karr
@JohnieKarr Je ne travaille plus avec .NET, donc je ne peux pas vraiment répondre. Cela dit, cette réponse ci-dessous semble montrer exactement ce que j'ai décrit
WickyNilliams
195

Je ne pense pas que l'attribut de validation min / max existe. J'utiliserais quelque chose comme

[Range(1, Int32.MaxValue)]

pour la valeur minimale 1 et

[Range(Int32.MinValue, 10)]

pour valeur maximale 10

Gars
la source
4
Mmm .. Pas tout à fait à l'aise avec ça. Cela me semble un peu piraté.
stiank81
21
C'est un peu hacky .. mais parfois les hacks me mettent plus à l'aise :)
Guy
4
Cette approche est correcte tant que vous remplacez le message d'erreur par défaut ou vous obtiendrez quelque chose d'horrible comme: "La propriété x doit être comprise entre -2e ^ 31-1 et 10".
Nine Tails
2
En quoi est-ce piraté et inconfortable? Cela me semble une bonne approche.
1
RangeAttributea AllowMultiple = false, donc cela ne peut pas compiler.
Daniel Schilling
38

Un exemple complet de la façon dont cela pourrait être fait. Pour éviter d'avoir à écrire des scripts de validation côté client, le ValidationType = "range" existant a été utilisé.

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;
    }

}
Mario
la source
8
Très bonne réponse. Je modifierais un peu le message d'erreur: «Entrez une valeur supérieure ou égale à» est un message d'erreur plus (grammaticalement) correct.
Tieson T.
0

jQuery Validation Plugin implémente déjà des règles min et max, il nous suffit de créer un adaptateur pour notre attribut personnalisé:

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;
    }
}

Adaptateur:

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

L'attribut Min serait très similaire.

Benas Radzevicius
la source