2009-02-21 10 views
137

Comment obtenir la collection d'erreurs dans une vue? Je ne souhaite pas utiliser le résumé de validation Helt Html ou le message de validation. Au lieu de cela, je veux vérifier les erreurs et, le cas échéant, les afficher dans un format spécifique. Aussi sur les contrôles d'entrée, je veux vérifier une erreur de propriété spécifique et ajouter une classe à l'entrée.Comment obtenir la collection d'erreurs d'état du modèle dans ASP.NET MVC?

P.S. J'utilise Spark View Engine mais l'idée devrait être la même.

donc je pensais que je pouvais faire quelque chose comme ...

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

....and also... 

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

.... 

Ou quelque chose comme ça.

MISE À JOUR

Ma solution finale ressemblait à ceci:

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

Cela ne fait qu'ajouter l'erreur classe css si cette propriété a une erreur.

+1

double possible de [Comment obtenir toutes les erreurs de ASP.Net MVC ModelState?] (Https://stackoverflow.com/questions/1352948/how-to-get-all-errors-from- asp-net-mvc-modelstate) –

Répondre

199
<% ViewData.ModelState.IsValid %> 

ou

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

et une propriété en particulier ...

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

Question - Comment obtenir l'erreur pour une propriété spécifique? –

+1

la propriété ModelState est de type dictionnaire pour obtenir l'erreur pour transmettre le nom de clé ViewData.ModelState [ « nom »] –

+0

concernant « ViewData.ModelState [ » propriété « ]. Les erreurs » serait-ce par une exception de référence null s'il n'y avait pas de clé avec le nom "Property"? serait-il préférable de vérifier d'abord null sur le ViewData.ModelState ["Property"] avant de lire dans les erreurs? – DaveH

5

Merci Tchad! Pour montrer toutes les erreurs associées à la clé, voici ce que j'ai trouvé. Pour une raison quelconque, l'aide de base Html.ValidationMessage affiche uniquement la première erreur associée à la clé.

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

obtenir juste les erreurs du ModelState, utilisez ce Linq:

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

cela lancerait-il une exception de référence nulle s'il n'y avait pas de clé avec le nom spécifié? serait-il préférable de vérifier d'abord null sur le ViewData.ModelState [clé] avant de lire dans les erreurs? – DaveH

+4

Parce que nous commençons par itérer sur this.ModelState.Keys, je ne vois pas le potentiel pour une KeyNotFoundException. Je pense que ce contrôle serait exagéré. –

0

Si vous ne savez pas ce que la propriété a causé l'erreur, vous pouvez , en utilisant la réflexion, boucle sur toutes les propriétés:

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

Où T est le type de votre "ViewModel".

28

Version condensée de @ChrisMcKenzie's answer:

var modelStateErrors = this.ModelState.Values.SelectMany(m => m.Errors); 
22

Cela vous donnera une chaîne avec toutes les erreurs avec virgule séparant

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

Voici le 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()) 
+1

beurk .. content que je n'utilise pas VB;) – cyclical

1

plusieurs réponses ensemble en train de mettre en haut, ce que je fini par utiliser:

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

validationErrors finit par être un List<string> qui contient chaque message d'erreur. De là, il est facile de faire ce que vous voulez avec cette liste.

enter image description here