Wie verwende ich Datenanmerkungen, um eine bedingte Validierung des Modells durchzuführen?
Nehmen wir zum Beispiel an, wir haben das folgende Modell (Person und Senior):
public class Person
{
[Required(ErrorMessage = "*")]
public string Name
{
get;
set;
}
public bool IsSenior
{
get;
set;
}
public Senior Senior
{
get;
set;
}
}
public class Senior
{
[Required(ErrorMessage = "*")]//this should be conditional validation, based on the "IsSenior" value
public string Description
{
get;
set;
}
}
Und die folgende Ansicht:
<%= Html.EditorFor(m => m.Name)%>
<%= Html.ValidationMessageFor(m => m.Name)%>
<%= Html.CheckBoxFor(m => m.IsSenior)%>
<%= Html.ValidationMessageFor(m => m.IsSenior)%>
<%= Html.CheckBoxFor(m => m.Senior.Description)%>
<%= Html.ValidationMessageFor(m => m.Senior.Description)%>
Ich möchte das bedingte Pflichtfeld "Senior.Description" sein, das auf der Auswahl der Eigenschaft "IsSenior" basiert (true -> erforderlich). Wie implementiere ich die bedingte Validierung in ASP.NET MVC 2 mit Datenanmerkungen?
c#
asp.net-mvc
forms
validation
Peter Stegnar
quelle
quelle
Senior
Objekt ist immer ein Senior. Warum kann IsSenior in diesem Fall falsch sein? Muss die Eigenschaft 'Person.Senior' nicht einfach null sein, wenn siePerson.IsSenior
falsch ist ? Oder warum nicht dieIsSenior
Eigenschaft wie folgt implementieren :bool IsSenior { get { return this.Senior != null; } }
.Antworten:
Es gibt eine viel bessere Möglichkeit, bedingte Validierungsregeln in MVC3 hinzuzufügen. Lassen Sie Ihr Modell
IValidatableObject
dieValidate
Methode erben und implementieren :Weitere Informationen finden Sie unter Einführung in ASP.NET MVC 3 (Vorschau 1) .
quelle
ModelState.IsValid
- nicht direkt Validate anrufenIch habe dies durch die Behandlung des "ModelState" gelöst. -Wörterbuch behandelt habe, das in der Steuerung enthalten ist. Das ModelState-Wörterbuch enthält alle Mitglieder, die validiert werden müssen.
Hier ist die Lösung:
Wenn Sie eine bedingte Validierung basierend auf einem Feld implementieren müssen (z. B. wenn A = true, ist B erforderlich), während Sie Fehlermeldungen auf Eigenschaftsebene beibehalten (dies gilt nicht für benutzerdefinierte Validatoren auf Objektebene), können Sie dies erreichen indem Sie "ModelState" behandeln, indem Sie einfach unerwünschte Validierungen daraus entfernen.
... In einer Klasse ...
... Klasse geht weiter ...
... In einer Controller-Aktion ...
...
Damit erreichen wir eine bedingte Validierung, während alles andere gleich bleibt.
AKTUALISIEREN:
Dies ist meine endgültige Implementierung: Ich habe eine Schnittstelle für das Modell und das Aktionsattribut verwendet, das das Modell validiert, das diese Schnittstelle implementiert. Die Schnittstelle schreibt die Validate-Methode (ModelStateDictionary modelState) vor. Das Attribut on action ruft nur Validate (modelState) für IValidatorSomething auf.
Ich wollte diese Antwort nicht komplizieren, deshalb habe ich die endgültigen Implementierungsdetails (die am Ende im Produktionscode eine Rolle spielen) nicht erwähnt.
quelle
Ich hatte gestern das gleiche Problem, aber ich habe es auf sehr saubere Weise gemacht, was sowohl für die clientseitige als auch für die serverseitige Validierung funktioniert.
Bedingung: Basierend auf dem Wert einer anderen Eigenschaft im Modell möchten Sie eine andere Eigenschaft erforderlich machen. Hier ist der Code
Hier ist PropertyName die Eigenschaft, für die Sie Ihre Bedingung festlegen möchten. DesiredValue ist der bestimmte Wert des PropertyName (der Eigenschaft), für den Ihre andere Eigenschaft für erforderlich validiert werden muss
Angenommen, Sie haben Folgendes
Registrieren Sie zu guter Letzt den Adapter für Ihr Attribut, damit es eine clientseitige Validierung durchführen kann (ich habe ihn in global.asax, Application_Start eingefügt).
quelle
Ich habe dieses erstaunliche Nuget verwendet, das dynamische Anmerkungen ExpressiveAnnotations ausführt
Sie können jede Logik validieren, von der Sie träumen können:
quelle
Sie können Validatoren bedingt deaktivieren, indem Sie Fehler aus ModelState entfernen:
quelle
Danke Merritt :)
Ich habe dies gerade auf MVC 3 aktualisiert, falls jemand es nützlich findet: Bedingte Validierung in ASP.NET MVC 3 .
quelle
Es gibt jetzt ein Framework, das diese bedingte Validierung (neben anderen praktischen Validierungen von Datenanmerkungen) sofort durchführt: http://foolproof.codeplex.com/
Schauen Sie sich insbesondere den Validator [RequiredIfTrue ("IsSenior")] an. Sie platzieren dies direkt in der Eigenschaft, die Sie validieren möchten, damit Sie das gewünschte Verhalten des Validierungsfehlers erhalten, der der Eigenschaft "Senior" zugeordnet ist.
Es ist als NuGet-Paket erhältlich.
quelle
Sie müssen auf Personenebene validieren, nicht auf Seniorenebene, oder Senior muss einen Verweis auf die übergeordnete Person haben. Es scheint mir, dass Sie einen Selbstvalidierungsmechanismus benötigen, der die Validierung für die Person und nicht für eine ihrer Eigenschaften definiert. Ich bin mir nicht sicher, aber ich glaube nicht, dass DataAnnotations dies sofort unterstützt. Was Sie tun können, um Ihre eigenen zu erstellen
Attribute
, die daraus abgeleitet werdenValidationAttribute
, kann auf Klassenebene dekoriert werden. Als Nächstes erstellen Sie einen benutzerdefinierten Validator, mit dem auch diese Validatoren auf Klassenebene ausgeführt werden können.Ich weiß, dass Validation Application Block die Selbstvalidierung sofort unterstützt, aber VAB hat eine ziemlich steile Lernkurve. Hier ist jedoch ein Beispiel für die Verwendung von VAB:
quelle
Ich hatte das gleiche Problem, brauchte eine Änderung des Attributs [Erforderlich] - Feld erforderlich in Abhängigkeit von der http-Anfrage. Die Lösung ähnelte der Antwort von Dan Hunex, aber seine Lösung funktionierte nicht richtig (siehe Kommentare). Ich verwende keine unauffällige Validierung, sondern nur MicrosoftMvcValidation.js. Hier ist es. Implementieren Sie Ihr benutzerdefiniertes Attribut:
Dann müssen Sie Ihren benutzerdefinierten Anbieter implementieren, um ihn als Adapter in Ihrer global.asax zu verwenden
Und ändern Sie Ihre global.asax mit einer Linie
und hier ist es
Der Hauptvorteil für mich ist, dass ich keinen benutzerdefinierten Client-Validator wie im Fall einer unauffälligen Validierung codieren muss. Es funktioniert genauso wie [Erforderlich], jedoch nur in den von Ihnen gewünschten Fällen.
quelle
DataAnnotationsModelValidator
war genau das, was ich sehen musste. Danke dir.Schauen Sie sich die bedingte Validierung von Simon Ince in MVC an .
Ich arbeite gerade an seinem Beispielprojekt.
quelle
Typische Verwendung zur bedingten Beseitigung von Fehlern aus dem Modellstatus:
Beispiel:
Behalten Sie in Ihrem Beispiel alles bei und fügen Sie die vorgeschlagene Logik zur Aktion Ihres Controllers hinzu. Ich gehe davon aus, dass in Ihrem an die Controller-Aktion übergebenen ViewModel die Objekte Person und Senior Person mit Daten aus der Benutzeroberfläche gefüllt sind.
quelle
Ich verwende MVC 5, aber Sie können Folgendes ausprobieren:
In Ihrem Fall würden Sie so etwas wie "IsSenior == true" sagen. Dann müssen Sie nur noch die Validierung Ihrer Post-Aktion überprüfen.
quelle