Як отримати колекцію помилок стану моделі в ASP.NET MVC?


145

Як отримати колекцію помилок у перегляді?

Я не хочу використовувати підсумок перевірки помічника Html або повідомлення про валідацію. Натомість я хочу перевірити наявність помилок та чи відображати їх у певному форматі. Також на елементах керування введенням я хочу перевірити конкретну помилку властивості та додати клас до вводу.

PS Я використовую Spark View Engine, але ідея повинна бути такою ж.

Тож я зрозумів, що можу зробити щось на кшталт ...

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

....and also...

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

....

Або щось подібне.

ОНОВЛЕННЯ

Моє остаточне рішення виглядало так:

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

Це додає клас css помилки лише в тому випадку, якщо в цьому властивості є помилка.


Відповіді:


210
<% ViewData.ModelState.IsValid %>

або

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

а для конкретного майна ...

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

1
Властивість ModelState має тип словника, щоб отримати помилку при передачі ключового імені ViewData.ModelState ["Ім'я"]

стосовно "ViewData.ModelState [" Властивості "]. Помилки" призведе до нульового посилання, якщо не було ключа з назвою "Властивість"? краще було б спочатку перевірити наявність null на ViewData.ModelState ["Властивість"] перед читанням у "Помилках"?
Девід Холлоуелл - MSFT

@DaveH Так, спочатку слід повністю перевірити наявність
Alex Lyman

61

Щоб просто отримати помилки від ModelState, використовуйте цей Linq:

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

2
це кине нульове посилання виключення, якщо б не було ключа із вказаним іменем? було б краще спочатку перевірити наявність null на ViewData.ModelState [клавіші] перед читанням у помилках?
Девід Холлоуелл - MSFT

5
Оскільки ми починаємо з ітерації над цим.ModelState.Keys, я не бачу потенціалу для KeyNotFoundException. Я думаю, що перевірка була б надмірною.
Кріс Макензі


28

Це дасть вам один рядок з усіма помилками з розділенням коми

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

Це єдине, що я знайшов у всьому цьому списку, який фактично виводить помилки! Спасибі
Джеймі

6

Дякую Чаде! Щоб показати всі помилки, пов’язані з ключем, ось що я придумав. Чомусь базовий помічник Html.ValidationMessage показує лише першу помилку, пов’язану з ключем.

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

Складаючи кілька відповідей зверху, це я закінчила:

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

validationErrorsв кінцевому підсумку є а, List<string>що містить кожне повідомлення про помилку. Звідти легко робити те, що ви хочете, із цим списком.

введіть тут опис зображення


2

Ось 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

Якщо ви не знаєте, яке властивість спричинило помилку, ви можете, використовуючи відображення, провести цикл на всі властивості:

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

Де T - тип вашого "ViewModel".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.