Bagaimana cara mendapatkan koleksi Model State Errors di ASP.NET MVC?

145

Bagaimana cara mendapatkan kumpulan kesalahan dalam tampilan?

Saya tidak ingin menggunakan Ringkasan Validasi Html atau Pesan Validasi. Sebaliknya saya ingin memeriksa kesalahan dan apakah ada yang menampilkannya dalam format tertentu. Juga pada kontrol input saya ingin memeriksa kesalahan properti tertentu dan menambahkan kelas ke input.

PS Saya menggunakan Spark View Engine tetapi idenya harus sama.

Jadi saya pikir saya bisa melakukan sesuatu seperti ...

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

....and also...

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

....

Atau semacam itu.

MEMPERBARUI

Solusi terakhir saya terlihat seperti ini:

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

Ini hanya menambah kelas kesalahan css jika properti ini memiliki kesalahan.

Ryan Montgomery
sumber
1
Kemungkinan duplikat dari Cara mendapatkan semua Kesalahan dari ASP.Net MVC modelState?
Michael Freidgeim

Jawaban:

210
<% ViewData.ModelState.IsValid %>

atau

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

dan untuk properti tertentu ...

<% ViewData.ModelState["Property"].Errors %> // Note this returns a collection
Chad Moran
sumber
1
properti ModelState adalah jenis kamus untuk mendapatkan kesalahan untuk melewati nama kunci ViewData.ModelState ["Name"]
mengenai "ViewData.ModelState [" Property "]. Kesalahan" apakah ini akan melempar pengecualian referensi nol jika tidak ada kunci dengan nama "Properti"? apakah lebih baik memeriksa dulu nol pada ViewData.ModelState ["Properti"] sebelum membaca dalam Kesalahan?
David Hollowell - MSFT
@ Dave Yap, Anda harus benar-benar memeriksa keberadaannya terlebih dahulu
Alex Lyman
61

Untuk mendapatkan kesalahan dari ModelState, gunakan Linq ini:

var modelStateErrors = this.ModelState.Keys.SelectMany(key => this.ModelState[key].Errors);
Chris McKenzie
sumber
2
apakah ini akan melempar pengecualian referensi nol jika tidak ada kunci dengan nama yang ditentukan? apakah akan lebih baik untuk terlebih dahulu memeriksa nol pada [key] ViewData.ModelState sebelum membaca di Kesalahan?
David Hollowell - MSFT
5
Karena kita mulai dengan mengulangi this.ModelState.Keys, saya tidak melihat potensi KeyNotFoundException. Saya pikir cek itu akan berlebihan.
Chris McKenzie
28

Ini akan memberi Anda satu string dengan semua kesalahan dengan memisahkan koma

string validationErrors = string.Join(",",
                    ModelState.Values.Where(E => E.Errors.Count > 0)
                    .SelectMany(E => E.Errors)
                    .Select(E => E.ErrorMessage)
                    .ToArray());
UshaP
sumber
Ini adalah satu-satunya hal yang saya temukan di seluruh daftar ini yang benar-benar mencetak kesalahan! Terima kasih
Jamie
6

Chad terima kasih! Untuk menunjukkan semua kesalahan yang terkait dengan kunci, inilah yang saya temukan. Untuk beberapa alasan, pembantu Html.ValidationMessage dasar hanya menampilkan kesalahan pertama yang terkait dengan kunci.

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

Mengumpulkan beberapa jawaban dari atas, inilah yang akhirnya saya gunakan:

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

validationErrorsakhirnya menjadi List<string>yang berisi setiap pesan kesalahan. Dari sana, mudah untuk melakukan apa yang Anda inginkan dengan daftar itu.

masukkan deskripsi gambar di sini

Casey Crookston
sumber
2

Inilah 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
sumber
0

Jika Anda tidak tahu properti apa yang menyebabkan kesalahan, Anda bisa, menggunakan refleksi, mengulang semua properti:

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

Di mana T adalah tipe "ViewModel" Anda.

Gerard
sumber