Come posso ottenere la raccolta di errori di stato del modello in ASP.NET MVC?


145

Come posso ottenere la raccolta di errori in una vista?

Non desidero utilizzare il riepilogo della convalida HTML o il messaggio di convalida. Invece voglio verificare la presenza di errori e se qualcuno li visualizza in un formato specifico. Anche sui controlli di input voglio verificare un errore di proprietà specifico e aggiungere una classe all'input.

PS Sto usando Spark View Engine ma l'idea dovrebbe essere la stessa.

Quindi ho pensato di poter fare qualcosa come ...

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

....and also...

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

....

O qualcosa di simile.

AGGIORNARE

La mia soluzione finale sembrava così:

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

Ciò aggiunge la classe css di errore solo se questa proprietà ha un errore.


Risposte:


210
<% ViewData.ModelState.IsValid %>

o

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

e per una proprietà specifica ...

<% ViewData.ModelState["Property"].Errors %> // Note this returns a collection

1
la proprietà ModelState è di tipo dizionario per ottenere l'errore per passare il nome chiave ViewData.ModelState ["Nome"]

per quanto riguarda "ViewData.ModelState [" Proprietà "]. Errori" genererebbe un'eccezione di riferimento null se non esistesse una chiave con il nome "Proprietà"? sarebbe meglio prima verificare la presenza di null su ViewData.ModelState ["Proprietà"] prima di leggere in Errori?
David Hollowell - MSFT

@DaveH Sì, dovresti prima controllare completamente l'esistenza
Alex Lyman il

61

Per ottenere gli errori da ModelState, utilizzare questo Linq:

var modelStateErrors = this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors);

2
ciò genererebbe un'eccezione di riferimento null se non esistesse una chiave con il nome specificato? sarebbe meglio prima verificare la presenza di null su ViewData.ModelState [chiave] prima di leggere in Errori?
David Hollowell - MSFT

5
Perché iniziamo ripetendo this.ModelState.Keys, non vedo il potenziale per un KeyNotFoundException. Penso che il controllo sarebbe eccessivo.
Chris McKenzie,


28

Questo ti darà una stringa con tutti gli errori con separazione delle virgole

string validationErrors = string.Join(",",
                    ModelState.Values.Where(E => E.Errors.Count > 0)
                    .SelectMany(E => E.Errors)
                    .Select(E => E.ErrorMessage)
                    .ToArray());

Questa è l'unica cosa che ho trovato in questo intero elenco che in realtà stampa gli errori! Grazie
Jamie,

6

Grazie Chad! Per mostrare tutti gli errori associati alla chiave, ecco cosa mi è venuto in mente. Per qualche motivo, l'helper di base Html.ValidationMessage mostra solo il primo errore associato alla chiave.

    <%= 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();
    }

6

Mettendo insieme diverse risposte dall'alto, questo è quello che ho finito per usare:

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

validationErrorsfinisce per essere un List<string>che contiene ogni messaggio di errore. Da lì, è facile fare quello che vuoi con quell'elenco.

inserisci qui la descrizione dell'immagine


2

Ecco il 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())

0

Se non sai quale proprietà ha causato l'errore, puoi, usando reflection, scorrere su tutte le proprietà:

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

Dove T è il tipo di "ViewModel".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.