ModelState.AddModelError - Bagaimana saya bisa menambahkan kesalahan yang bukan untuk properti?

190

Saya memeriksa basis data saya Create(FooViewModel fvm){...}untuk melihat apakah fvm.prop1dan fvm.prop2sudah ada dalam kombinasi itu; jika demikian, saya ingin menambahkan kesalahan ke modelstate, lalu kembalikan seluruh tampilan. Saya mencoba:

public ActionResult Create(FooViewModel fvm){
    if (ThatComboAlreadyExists(fvm)) {
      ModelState.AddModelError("Model", "There is already one like that");
      return View(fvm);
    }
}

... tapi saya tidak mendapatkan tampilan kesalahan dalam Html.ValidationSummary, di situlah saya menganggap mereka akan muncul. Saya curiga "Model" bukan kunci yang tepat, tetapi saya belum dapat menemukan apa pun ala Google.

Scott Baker
sumber

Jawaban:

330

Saya akhirnya menemukan contoh penggunaan yang saya cari - untuk menetapkan kesalahan pada Model secara umum, bukan salah satu sifatnya, seperti biasa Anda sebut:

ModelState.AddModelError(string key, string errorMessage);

tetapi gunakan string kosong untuk kunci:

ModelState.AddModelError(string.Empty, "There is something wrong with Foo.");

Pesan kesalahan akan muncul dengan sendirinya <%: Html.ValidationSummary() %>seperti yang Anda harapkan.

Scott Baker
sumber
22
Kasus ini membuat saya berpikir: Mengapa tidak ada metode seperti ModelState.AddError(errorMessage)atau ModelState.AddGlobalError(errorMessage)... itu akan menjadi intuitif dan lebih mudah untuk mengetahui cara menambahkan pesan kesalahan yang tidak terkait dengan properti model mana pun.
Rubens Mariuzzo
@ Ruben: Benar, tetapi Anda dapat dengan mudah menambahkan metode seperti itu dengan metode ekstensi.
Johnny5
2
Anda juga dapat menampilkan kesalahan menggunakan@Html.ValidationMessage(string.Empty)
Ben Foster
menjadi properti model Anda terikat pada tampilan - yang memiliki kesalahan - hanya untuk menjadi jelas.
niico
1
The ValidationSummaryErrors(bool excludePropertyErrors)berlebihan akan menampilkan semua kesalahan validasi jika argumen adalah palsu atau hanya non-properti-spesifik (key = "") kesalahan jika argumen adalah benar.
Suncat2000
26

Anda dapat menambahkan kesalahan model pada properti apa pun dari model Anda, saya sarankan jika tidak ada yang terkait dengan membuat properti baru.

Sebagai contoh, kami memeriksa apakah email sudah digunakan dalam DB dan menambahkan kesalahan ke properti Email dalam tindakan sehingga ketika saya mengembalikan tampilan, mereka tahu bahwa ada kesalahan dan cara menampilkannya dengan menggunakan

<%: Html.ValidationSummary(true)%>
<%: Html.ValidationMessageFor(model => model.Email) %>

dan

ModelState.AddModelError("Email", Resources.EmailInUse);
VinnyG
sumber
1
Ini tampaknya berlawanan dengan intuisi dalam kasus saya - saya sedang memeriksa untuk melihat apakah kombinasi tertentu dari col1 & col2 sudah ada dalam database, jadi sepertinya tidak tepat untuk memiliki properti IsDuplicateOfAnotherRow di ViewModel saya. Ternyata, Anda dapat menambahkan kesalahan ke model Anda - lihat jawaban saya.
Scott Baker
1
Apakah ada cara untuk mendapatkan string "Email" untuk AddModelError tanpa menggunakan string literal yang rapuh? Suka (m=>m.email).SomeMagicToString()?
Snekse
Saya rasa tidak, Anda harus menggunakan string sihir ... bukan yang terbaik tetapi masih merupakan solusi yang bagus
VinnyG
4
The nameofOperator datang C # 6.0 memecahkan masalah string yang ajaib ini. msdn.microsoft.com/en-us/magazine/dn802602.aspx
RJ Cuthbertson
3

Menempatkan properti model dot dalam string berhasil bagi saya: ModelState.AddModelError("Item1.Month", "This is not a valid date");

Chris
sumber
2
Itu memang akan menunjukkan Bulan tidak valid di UI Anda, tetapi itu tidak menyelesaikan masalah aslinya.
Scott Baker
2
Masalah aslinya berasal dari tidak memahami apa yang "kunci" wakili dalam metode ini. Ini menyoroti cara "kunci" berfungsi, jadi ada baiknya mengetahui bahwa kunci tidak harus hanya berupa nama properti, tetapi juga bisa merujuk ke properti bersarang atau nilai khusus String.Empty.
Triynko