2009-02-21 16 views
137

Jak uzyskać kolekcję błędów w widoku?Jak uzyskać kolekcję błędów stanu modelu w środowisku ASP.NET MVC?

Nie chcę używać podsumowania sprawdzania poprawności html ani komunikatu sprawdzania poprawności. Zamiast tego chcę sprawdzić błędy i wyświetlić je w określonym formacie. Również na kontrolkach wejścia chcę sprawdzić konkretny błąd właściwości i dodać klasę do wejścia.

P.S. Używam silnika Spark View Engine, ale pomysł powinien być taki sam.

więc pomyślałam mógłby zrobić coś jak ...

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

....and also... 

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

.... 

czy coś takiego.

UPDATE

Moje ostateczne rozwiązanie wyglądało tak:

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

To tylko dodaje klasę css błędzie, jeśli ta właściwość ma błąd.

+1

Możliwy duplikat [Jak uzyskać wszystkie błędy z ASP.NET MVC ModelState?] (Https://stackoverflow.com/questions/1352948/how-to-get-all-errors-from- asp-net-mvc-modelstate) –

Odpowiedz

199
<% ViewData.ModelState.IsValid %> 

lub

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

i dla konkretnej nieruchomości ...

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

Pytanie - Jak uzyskać błąd dla określonej właściwości? –

+1

własnością ModelState jest słowniku typu aby uzyskać błędu dla zabicia nazwę klucza ViewData.ModelState [ „nazwa”] –

+0

dotyczące „ViewData.ModelState [” Property „]. Błędy” byłoby to rzucać wyjątku null odniesienia czy nie było klucza z nazwą "Nieruchomość"? byłoby lepiej najpierw sprawdzić zerowy na ViewData.ModelState ["Property"] przed odczytaniem w Błędy? – DaveH

5

Dzięki Czad! Aby pokazać wszystkie błędy związane z kluczem, oto co wymyśliłem. Z jakiegoś powodu podstawowy helper Html.ValidationMessage pokazuje tylko pierwszy błąd związany z kluczem.

<%= 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

Aby prostu błędy z ModelState, użyj tego Linq:

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

, czy to spowodowałoby wyjątek odwołania zerowego, gdyby nie było klucza o podanej nazwie? byłoby lepiej najpierw sprawdzić null na ViewData.ModelState [key] przed odczytaniem w Błędy? – DaveH

+4

Ponieważ zaczynamy od powtarzania tego.ModelState.Keys, nie widzę potencjału wyjątku KeyNotFoundException. Myślę, że czek byłby przesadą. –

0

Jeśli nie wiem, co własność spowodował błąd, można , używając odbicia, pętla we wszystkich właściwościach:

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

Gdzie T to typ twojego "ViewModel".

22

To daje jeden ciąg z wszystkich błędów z przecinek oddzielający

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

Oto 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

fuj .. cieszę się, że nie używam VB;) – cyclical

1

Zestawiając kilka odpowiedzi z góry, to jest to, co skończyło się przy użyciu:

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

validationErrors kończy się bycie List<string> który zawiera każdą wiadomość o błędzie. Stamtąd łatwo zrobić to, co chcesz z tą listą.

enter image description here

Powiązane problemy