ModelState.IsValid == false, warum?

120

Wo finde ich die Liste der Fehler, die den ModelState ungültig machen? Ich habe keine Fehlereigenschaft für das ModelState-Objekt gesehen.

Omu
quelle

Antworten:

45

Über "Kann es sein, dass 0 Fehler und IsValid == false": Hier ist der MVC-Quellcode von https://github.com/Microsoft/referencesource/blob/master/System.Web/ModelBinding/ModelStateDictionary.cs#L37-L41

public bool IsValid {
    get {
        return Values.All(modelState => modelState.Errors.Count == 0);
    }
}

Nun sieht es so aus, als ob es nicht sein kann. Nun, das ist für ASP.NET MVC v1.

Königin3
quelle
es scheint mir, dass es nicht sollte, ist etwas falsch in Values.All (modelState => modelState.Errors.Count == 0)?
Omu
Beachten Sie, dass der Fehler eine Nachricht oder eine Ausnahme sein kann. Zum Beispiel zeigt Html.ValidationSummary keine Ausnahmen an (aus Sicherheitsgründen, denke ich); Vielleicht sehen Sie deshalb keine Fehler? Wie prüft man, ob keine Fehler vorliegen?
Königin3
1
ModelState.IsValid gibt false
Omu
Ha-ha, das ist offensichtlich ... wie prüft man, ob "Werte 0 Fehler haben"?
Königin3
258

Da Sie wahrscheinlich in Visual Studio programmieren, sollten Sie die Möglichkeit nutzen, Haltepunkte für so einfache Debugging-Schritte zu verwenden (um eine Vorstellung davon zu bekommen, wie das Problem in Ihrem Fall ist). Platzieren Sie sie einfach vor / an der Stelle, an der Sie ModelState.isValid überprüfen, und bewegen Sie den Mauszeiger über den ModelState. Jetzt können Sie einfach alle darin enthaltenen Werte durchsuchen und feststellen, welcher Fehler die isvalid-Rückgabe false verursacht.

Modellzustand

bastijn
quelle
3
Könnte es möglich sein, dass alle Werte 0 Fehler haben und der Modellstatus immer noch ungültig ist?
Omu
wie oben gesagt, nein das ist nicht möglich :). Irgendwo muss eine Fehlerzahl sein! = 0.
Bastijn
2
Wenn die ErrorMessage für Sie nicht eindeutig ist, können Sie als Add-On zu den Schlüsseln gehen und sehen, auf welche Variable sie sich bezieht.
Leuchtend
1
Führen Sie in Ihrer Ansicht Folgendes aus: @ Html.HiddenFor (model => model.Username) löst das Problem!
Umit Kaya
1
var asdf = ModelState.Values.Where(v => v.Errors.Count > 0);kann Ihnen helfen
Cirelli94
37

Fügen Sie den folgenden Code in das ActionResult Ihres Controllers ein und platzieren Sie den Debugger an dieser Stelle.

var errors = ModelState
    .Where(x => x.Value.Errors.Count > 0)
    .Select(x => new { x.Key, x.Value.Errors })
    .ToArray();
Krishna
quelle
3
Beste Antwort hier, sollte höher bewertet werden. Warum meine Zeit damit verbringen, 5 Ebenen des ModelState-Objekts im Debugger zu durchsuchen, wenn ich nur die Fehler daraus ziehen kann? Ich wäre den ganzen Morgen dort, wenn ich der am höchsten bewerteten Antwort folgen würde
Sean T
2
Dies ist das beste
Spielzeug
23
bool hasErrors =  ViewData.ModelState.Values.Any(x => x.Errors.Count > 1);

oder iterieren mit

    foreach (ModelState state in ViewData.ModelState.Values.Where(x => x.Errors.Count > 0))
    {

    }
Michael G.
quelle
Könnte es möglich sein, dass alle Werte 0 Fehler haben und der Modellstatus immer noch ungültig ist?
Omu
1
Der Modellstatus hat einen Schlüssel "Eigenschaft" und einen zugehörigen Fehler im Wörterbuch. Die Fehlermeldung könnte leer sein, aber die Fehleranzahl gibt die Anzahl der ungültigen Eigenschaften wieder. Da die ModelStateDictionary.AddModelError-Methode einen Schlüssel und eine Ausnahme- oder Fehlerzeichenfolge verwendet; Es ist erforderlich, einen Modellfehler hinzuzufügen.
Michael G
13

Manchmal löst ein Ordner eine Ausnahme ohne Fehlermeldung aus. Sie können die Ausnahme mit dem folgenden Snippet abrufen, um herauszufinden, was falsch ist:

(Oft, wenn der Ordner versucht, Zeichenfolgen in komplexe Typen usw. zu konvertieren.)

 if (!ModelState.IsValid)
            {
var errors = ModelState.SelectMany(x => x.Value.Errors.Select(z => z.Exception));

// Breakpoint, Log or examine the list with Exceptions.

  }
Jonas Stensved
quelle
1
Dieser Code war für mich sehr hilfreich, aber das Iterieren der Fehler (Ausnahmen), um jede .Message zu erhalten, führte zu "Objektreferenz nicht auf eine Instanz eines Objekts festgelegt". Als ich z.Exception in z.ErrorMessage geändert habe, konnte ich die Fehlermeldungen anzeigen.
StackOverflowUser
Dies war die Lösung für mich, als ich zu z.ErrorMessage wechselte, obwohl ich mit z.Exception keinen Fehler bekam, sondern nur Nullwerte. Wahrscheinlich lohnt es sich, die ursprüngliche Antwort zu aktualisieren.
besonders
5

Wenn Sie die Prüfung für ModelsState.IsValid entfernen und einen Fehler zulassen, erhalten Sie beim Kopieren dieser Zeile ((System.Data.Entity.Validation.DbEntityValidationException)$exception).EntityValidationErrorsund Einfügen in den Überwachungsabschnitt in Visual Studio genau den Fehler. Spart viel Zeit bei der Überprüfung, wo der Fehler liegt.

Tom McDonough
quelle
1
Wirklich hilfreicher Tipp.
Ash
Dies ist der beste Rat in diesem Thread. Das Problem, das ich hatte, war ein dummes "." (Punkt) in Benutzername
Mangia
3

Die ModelState-Eigenschaft auf dem Controller ist tatsächlich ein ModelStateDictionary-Objekt. Sie können die Schlüssel im Wörterbuch durchlaufen und mithilfe der IsValidField-Methode überprüfen, ob dieses bestimmte Feld gültig ist.

Tvanfosson
quelle
3

Wie mir gerade passiert ist, kann dies auch passieren, wenn Sie Ihrem Modell eine erforderliche Eigenschaft hinzufügen, ohne Ihr Formular zu aktualisieren. In diesem Fall listet die ValidationSummary die Fehlermeldung nicht auf.

AndyP9
quelle
1
Das ist mir passiert. Danke für den Tipp!
Lewis86