Min / Max-Wert-Validatoren in asp.net mvc

106

Die Validierung mit Attributen in asp.net mvc ist wirklich nett. Ich habe den [Range(min, max)]Validator bisher zum Überprüfen von Werten verwendet, wie z.

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

Jetzt muss ich jedoch den Min- und Max-Zustand separat prüfen. Ich hatte erwartet, Attribute wie diese zu finden:

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

Gibt es vordefinierte Attribute zum Schreiben? Oder wie erreiche ich das?

stiank81
quelle
FluentValidation kann eine andere Lösung sein, um den Datumsbereich zu lösen. Hier ist meine Antwort auf eine andere Frage, die hilfreich sein könnte .
Zinov

Antworten:

48

Hier ist, wie ich einen Validator für MaxValue schreiben würde

public class MaxValueAttribute : ValidationAttribute
    {
        private readonly int _maxValue;

        public MaxValueAttribute(int maxValue)
        {
            _maxValue = maxValue;
        }

        public override bool IsValid(object value)
        {
            return (int) value <= _maxValue;
        }
    }

Das MinValue-Attribut sollte ziemlich gleich sein

Charles Ouellet
quelle
Ok, hatte erwartet, dass sie existieren, aber fair genug, um sie zu schreiben. Vielen Dank!
stiank81
1
Nur zu Ihrer Information, dies würde das Formular auf der Javascript-Seite nicht auf magische Weise validieren. Sie müssten dafür zusätzlichen Code + js schreiben.
Basarat
3
@basarat Eigentlich brauchen Sie kein zusätzliches JS, die jquery-Validierungsbibliothek hat bereits Funktionen für min / max. Sie müssen nur die IClientValidationSchnittstelle für das obige Attribut implementieren und die korrekten Werte von der GetClientValidationRulesMethode zurückgeben
WickyNilliams
@WickyNilliams Würden Sie eine Antwort mit einem Beispiel für Ihren Kommentar hinzufügen, oder CharlesOuellet, werden Sie diese Antwort mit einem Beispiel für Wickys Kommentar bearbeiten? Ich würde gerne ein funktionierendes Beispiel unterstützen, das eine clientseitige Validierung beinhaltet.
Johnie Karr
@JohnieKarr Ich arbeite nicht mehr mit .NET, daher kann ich keine gute Antwort geben. Das heißt, diese Antwort unten scheint genau das zu zeigen, was ich beschrieben habe
WickyNilliams
195

Ich glaube nicht, dass ein Min / Max-Validierungsattribut existiert. Ich würde so etwas benutzen

[Range(1, Int32.MaxValue)]

für Mindestwert 1 und

[Range(Int32.MinValue, 10)]

für Maximalwert 10

Kerl
quelle
4
Mmm .. Nicht ganz bequem damit. Sieht für mich ein bisschen hackig aus.
stiank81
21
Es ist ein bisschen hacky .. aber manchmal fühlen mich Hacks wohler :)
Guy
4
Dieser Ansatz ist in Ordnung, solange Sie die Standardfehlermeldung überschreiben, oder Sie erhalten etwas Schreckliches wie: "Eigenschaft x muss zwischen -2e ^ 31-1 und 10 liegen".
Neun Schwänze
2
Wie ist das hacky und unangenehm? Scheint mir eine gute Annäherung zu sein.
1
RangeAttributehat AllowMultiple = false, kann dies also nicht kompilieren.
Daniel Schilling
38

Ein vollständiges Beispiel dafür, wie dies getan werden könnte. Um zu vermeiden, dass clientseitige Validierungsskripte geschrieben werden müssen, wurde der vorhandene ValidationType = "range" verwendet.

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
quelle
8
Gute Antwort. Ich würde die Fehlermeldung ein wenig ändern: "Geben Sie einen Wert größer oder gleich ein" ist eine korrektere (grammatikalisch) korrekte Fehlermeldung.
Tieson T.
0

Das jQuery Validation Plugin implementiert bereits Min- und Max-Regeln. Wir müssen lediglich einen Adapter für unser benutzerdefiniertes Attribut erstellen:

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

Adapter:

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

Das Min-Attribut wäre sehr ähnlich.

Benas Radzevicius
quelle