Wie erhalte ich die Sammlung von Modellstatusfehlern in ASP.NET MVC?

145

Wie erhalte ich die Fehlersammlung in einer Ansicht?

Ich möchte weder die HTML-Helfer-Validierungszusammenfassung noch die Validierungsnachricht verwenden. Stattdessen möchte ich nach Fehlern suchen und diese in einem bestimmten Format anzeigen. Auch bei den Eingabesteuerelementen möchte ich nach einem bestimmten Eigenschaftsfehler suchen und der Eingabe eine Klasse hinzufügen.

PS Ich verwende die Spark View Engine, aber die Idee sollte dieselbe sein.

Also dachte ich mir, ich könnte so etwas wie ...

<if condition="${ModelState.Errors.Count > 0}">
  DispalyErrorSummary()
</if>

....and also...

<input type="text" value="${Model.Name}" 
       class="?{ModelState.Errors["Name"] != string.empty} error" />

....

Oder etwas ähnliches.

AKTUALISIEREN

Meine endgültige Lösung sah folgendermaßen aus:

<input type="text" value="${ViewData.Model.Name}" 
       class="text error?{!ViewData.ModelState.IsValid && 
                           ViewData.ModelState["Name"].Errors.Count() > 0}" 
       id="Name" name="Name" />

Dies fügt die Fehler-CSS-Klasse nur hinzu, wenn diese Eigenschaft einen Fehler aufweist.

Ryan Montgomery
quelle
1
Mögliches Duplikat von Wie bekomme ich alle Fehler von ASP.Net MVC modelState?
Michael Freidgeim

Antworten:

210
<% ViewData.ModelState.IsValid %>

oder

<% ViewData.ModelState.Values.Any(x => x.Errors.Count >= 1) %>

und für eine bestimmte Eigenschaft ...

<% ViewData.ModelState["Property"].Errors %> // Note this returns a collection
Chad Moran
quelle
1
Die ModelState-Eigenschaft ist vom Typ Wörterbuch, um den Fehler beim Übergeben des Schlüsselnamens ViewData.ModelState ["Name"]
in Bezug auf "ViewData.ModelState [" Property "]. Errors" würde dies eine Nullreferenzausnahme auslösen, wenn es keinen Schlüssel mit dem Namen "Property" gäbe? Wäre es besser, zuerst die ViewData.ModelState ["Eigenschaft"] auf Null zu prüfen, bevor Sie Fehler einlesen?
David Hollowell - MSFT
@ DaveH Ja, Sie sollten zuerst unbedingt auf Existenz prüfen
Alex Lyman
61

Verwenden Sie diese Linq, um nur die Fehler vom ModelState abzurufen:

var modelStateErrors = this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors);
Chris McKenzie
quelle
2
Würde dies eine Nullreferenzausnahme auslösen, wenn es keinen Schlüssel mit dem angegebenen Namen gäbe? Wäre es besser, zuerst den ViewData.ModelState [Schlüssel] auf Null zu prüfen, bevor Sie Fehler einlesen?
David Hollowell - MSFT
5
Da wir zunächst über this.ModelState.Keys iterieren, sehe ich kein Potenzial für eine KeyNotFoundException. Ich denke, dieser Scheck wäre übertrieben.
Chris McKenzie
28

Dies gibt Ihnen eine Zeichenfolge mit allen Fehlern mit Kommatrennung

string validationErrors = string.Join(",",
                    ModelState.Values.Where(E => E.Errors.Count > 0)
                    .SelectMany(E => E.Errors)
                    .Select(E => E.ErrorMessage)
                    .ToArray());
UshaP
quelle
Dies ist das einzige, was ich in dieser gesamten Liste gefunden habe, das die Fehler tatsächlich druckt! Vielen Dank
Jamie
6

Danke Chad! Um alle mit dem Schlüssel verbundenen Fehler anzuzeigen, habe ich mir Folgendes ausgedacht. Aus irgendeinem Grund zeigt der Basis-Html.ValidationMessage-Helfer nur den ersten Fehler an, der dem Schlüssel zugeordnet ist.

    <%= Html.ShowAllErrors(mykey) %>

HtmlHelper:

    public static String ShowAllErrors(this HtmlHelper helper, String key) {
        StringBuilder sb = new StringBuilder();
        if (helper.ViewData.ModelState[key] != null) {
            foreach (var e in helper.ViewData.ModelState[key].Errors) {
                TagBuilder div = new TagBuilder("div");
                div.MergeAttribute("class", "field-validation-error");
                div.SetInnerText(e.ErrorMessage);
                sb.Append(div.ToString());
            }
        }
        return sb.ToString();
    }
Rake36
quelle
6

Nachdem ich einige Antworten von oben zusammengestellt habe, habe ich Folgendes verwendet:

var validationErrors = ModelState.Values.Where(E => E.Errors.Count > 0)
    .SelectMany(E => E.Errors)
    .Select(E => E.ErrorMessage)
    .ToList();

validationErrorsendet damit, List<string>dass jede Fehlermeldung enthalten ist. Von dort aus können Sie mit dieser Liste ganz einfach das tun, was Sie wollen.

Geben Sie hier die Bildbeschreibung ein

Casey Crookston
quelle
2

Hier ist der VB.

Dim validationErrors As String = String.Join(",", ModelState.Values.Where(Function(E) E.Errors.Count > 0).SelectMany(Function(E) E.Errors).[Select](Function(E) E.ErrorMessage).ToArray())
MaylorTaylor
quelle
0

Wenn Sie nicht wissen, welche Eigenschaft den Fehler verursacht hat, können Sie mithilfe von Reflection alle Eigenschaften durchlaufen:

public static String ShowAllErrors<T>(this HtmlHelper helper) {
    StringBuilder sb = new StringBuilder();
    Type myType = typeof(T);
    PropertyInfo[] propInfo = myType.GetProperties();

    foreach (PropertyInfo prop in propInfo) {
        foreach (var e in helper.ViewData.ModelState[prop.Name].Errors) {
            TagBuilder div = new TagBuilder("div");
            div.MergeAttribute("class", "field-validation-error");
            div.SetInnerText(e.ErrorMessage);
            sb.Append(div.ToString());
        }
    }
    return sb.ToString();
}

Wobei T der Typ Ihres "ViewModel" ist.

Gerard
quelle