MVC3 ModelState-Fehler entfernen

81

Ich habe eine Situation, in der ich ein Bild hochlade, das der Benutzer aus seinem lokalen Dateisystem ausgewählt hat. Mein Formular hat meiner Ansicht nach grundsätzlich zwei Senden-Schaltflächen. Eine wird verwendet, um das Formular normal zu senden, und alle Überprüfungen werden ausgeführt. Die zweite dient nur zum Hochladen des Bildes. In diesem Fall möchte ich sie noch nicht validieren.

Ich habe es geschafft, die clientseitige Validierung zu deaktivieren, indem ich meiner Senden-Schaltfläche "Bild hochladen" den Klassenwert "Stilname abbrechen" gegeben habe

<input type="submit" name="UploadImageButton" value="Upload Image" class="style-name cancel" /> 

Wenn ich jetzt zurückschicke, hat mein Modell die Eigenschaft UploadImageButton. Wenn Sie auf diese Schaltfläche klicken, wird diese Eigenschaft ausgefüllt (der Name der Eingabe stimmt mit der Eigenschaft überein). Auf diese Weise weiß ich, ob das Formular über meine wahre Schaltfläche "Senden" oder über den UploadImageButton gesendet wurde.

Meine Frage lautet: Wie kann ich die ServerSide-Validierung deaktivieren? Ich möchte nicht, dass die Informationen zur Validierungszusammenfassung angezeigt werden, wenn der Benutzer auf diese Schaltfläche klickt. Ich weiß, dass Sie damit benutzerdefinierte Modellfehler hinzufügen können

ModelState.AddModelError("{key}", "{error msg}");

Ich suche nach einem Mittel, um Modellfehler zu entfernen. Ist das möglich?

BEARBEITEN:

Folgendes habe ich mir ausgedacht:

foreach (var key in ModelState.Keys.ToList().Where(key => ModelState.ContainsKey(key))) {
     //ModelState.Remove(key); //This was my solution before
     ModelState[key].Errors.Clear(); //This is my new solution. Thanks bbak
}
Jeff Reddy
quelle
Warum machst du eine Where(key => ModelState.Keys.Contains(key))? Es scheint, dass die Where-Klausel redundant ist, da für jeden Schlüssel in ModelState.Keys ModelState.Keys.Contains (Schlüssel) true zurückgibt.
Maxim Zaslavsky
1
Ich habe die Frage und den Text aktualisiert, um die kürzere Methode für ModelState.ContainsKey zu verwenden, obwohl Sie in Ihrer Annahme falsch liegen. Diese machen das Gleiche.
Jeff Reddy
Entschuldigung, ich habe Ihre Antwort möglicherweise schlecht erklärt oder falsch verstanden. Sie haben Recht damit ModelState.ContainsKey(key)und ModelState.Contains(key)tun dasselbe, aber mein Punkt ist, dass alle Werte in ModelState.Keys.ToList()will von Natur aus enthalten sind ModelState, sodass die gesamte WhereKlausel redundant ist und die Leistung verlangsamt. Kleinigkeit allerdings.
Maxim Zaslavsky
Das war ReSharper, der das zusammengeschmissen hat. Vielen Dank für den Hinweis.
Jeff Reddy
1
Beachten Sie einfach, wie Sie herausfinden, welche Schaltfläche die Quelle der Übermittlung war. Im ViewModel muss diese Eigenschaft nicht vorhanden sein. Fügen Sie dem Controller einfach einen FormCollection-Parameter hinzu: public ActionResult Index (YourViewModelClass-Modell, FormCollection formCollection). Und überprüfen Sie, ob der Schaltflächenname darin enthalten ist: if (formCollection ["UploadImageButton"]! = Null). Ich denke, es ist besser, wenn Sie mehr Submit-Button haben.
jannagy02

Antworten:

142

Sie können Modellfehler folgendermaßen entfernen:

if (ModelState.ContainsKey("{key}"))
    ModelState["{key}"].Errors.Clear();
bbak
quelle
1
Genau das habe ich gesucht. Ich habe meine ausgewählte Antwort geändert (sorry Adam Tuliper).
Jeff Reddy
Danke, das hat mir nur ein paar Stunden erspart!
Agent007
1
Nur für den Fall, dass sich jemand wundert, betrifft dies auchModelState.IsValid
Red Taz
2
Seltsamerweise war das in meinem Fall nicht genug. Ich musste ModelState ["{key}"] hinzufügen. ValidationState = ModelValidationState.Valid;
AGuyCalledGerald
67

Dies baut auf früheren Antworten auf, vereinfacht sie jedoch ein wenig mehr:

foreach (var modelValue in ModelState.Values)
{
    modelValue.Errors.Clear();
}
Dan Friedman
quelle
7

Im Allgemeinen möchten Sie die serverseitige Validierung nicht deaktivieren oder ModelState-Fehler nicht manuell entfernen. Es ist machbar, aber fehleranfällig, da es sich auf Zeichenfolgen als Schlüssel stützen muss. Ich habe die Antwort zum Entfernen der Schlüssel positiv bewertet, da sie korrekt und nützlich ist. Ich empfehle jedoch, sich nicht in einen Fall zu verwandeln, in dem Sie dies unbedingt berücksichtigen müssen.

In Ihrem Fall haben Sie mehrere Senden-Schaltflächen für dasselbe Formular, aber Sie senden das Formular wirklich nicht, wenn Sie das Bild hochladen. Um die clientseitige Validierung zu verhindern, können Sie die Klasse "Abbrechen" verwenden, wie Sie bereits angegeben haben. Ich empfehle jedoch auch, die zweite Schaltfläche zum Senden in einem anderen Formular zu verwenden. In diesem Fall führt dies zu keiner Validierung in Ihrem Hauptformular.

Die Verwendung des anderen Formulars bietet einen zweiten Vorteil: Sie können es an eine andere ActionResult-Methode senden, die nur die Logik des Hochladens des Bildes übernimmt. Diese andere Methode würde sich einfach nicht die Mühe machen, die "IsValid" -Eigenschaft des Modellstatus zu überprüfen: Es ist nur wichtig, ob das Bild Informationen enthält, und diese können separat überprüft werden. (Auch wenn Sie dieselbe ActionResult-Methode verwenden, können Sie die Logik so weiterleiten, dass Sie sich nicht auf die IsValid-Eigenschaft des Modellstatus verlassen.)

Wenn Sie die Fehler aus dem Modellstatus löschen müssen und es sinnvoll ist, alle zu löschen, versuchen Sie Folgendes:

foreach (var key in ModelState.Keys)
{
    ModelState[key].Errors.Clear();
}

Dies verhindert, dass Sie davon abhängen, ob die Schlüsselnamen korrekt sind, behält jedoch die Werte bei, falls bereits Werte (gültig oder ungültig) im Modell vorhanden sind.

Eine letzte Sache, die in diesen Fällen überprüft werden muss, ist, ob Sie Werte haben, die nur manchmal in der Ansicht enthalten sind, die keine clientseitige Validierung verursachen (sie sind nicht in der Ansicht), aber zu serverseitigen Validierungsproblemen führen. In diesem Fall ist es am besten, @ Html.HiddenFor (model => model.PropertyName zu verwenden. Wenn Sie können, wird der Wert in dieser Ansicht einfach nicht angezeigt, sofern er bereits festgelegt wurde.

James
quelle
7

Ich benutze es manchmal, also habe ich eine Erweiterungsmethode daraus gemacht:

public static ModelStateDictionary ClearError(this ModelStateDictionary m, string fieldName)
{
    if (m.ContainsKey(fieldName))
        m[fieldName].Errors.Clear();
    return m;
}

Es kann fließend verwendet werden, um Fehler für mehrere Felder zu löschen.

Mahmoodvcs
quelle
2

Verwenden Sie ModelState.Remove ("{key}"), um den Fehler aus dem Modell zu entfernen, wodurch ModelState.IsValid auf true zurückgesetzt wird

ModelState.Remove("{key}");
Ibrar
quelle