Adakah yang bisa memberi saya definisi singkat tentang peran ModelState di Asp.net MVC (atau tautan ke salah satunya). Secara khusus saya perlu tahu dalam situasi apa yang perlu atau diinginkan untuk menelepon ModelState.Clear()
.
Agak terbuka ya ... maaf, saya pikir mungkin membantu jika memberi tahu Anda apa yang sebenarnya saya lakukan:
Saya memiliki Tindakan Edit pada Pengontrol yang disebut "Halaman". Ketika saya pertama kali melihat formulir untuk mengubah detail Halaman semuanya dimuat dengan baik (mengikat ke objek "MyCmsPage"). Lalu saya klik tombol yang menghasilkan nilai untuk salah satu bidang objek MyCmsPage ( MyCmsPage.SeoTitle
). Ini menghasilkan fine dan memperbarui objek dan saya kemudian mengembalikan hasil tindakan dengan objek halaman yang baru dimodifikasi dan mengharapkan kotak teks yang relevan (diberikan menggunakan <%= Html.TextBox("seoTitle", page.SeoTitle)%>
) untuk diperbarui ... tetapi sayangnya ini menampilkan nilai dari model lama yang dimuat.
Saya telah mengatasinya dengan menggunakan ModelState.Clear()
tetapi saya perlu tahu mengapa / bagaimana cara kerjanya jadi saya tidak hanya melakukannya secara membabi buta.
PageController:
[AcceptVerbs("POST")]
public ActionResult Edit(MyCmsPage page, string submitButton)
{
// add the seoTitle to the current page object
page.GenerateSeoTitle();
// why must I do this?
ModelState.Clear();
// return the modified page object
return View(page);
}
Aspx:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyCmsPage>" %>
....
<div class="c">
<label for="seoTitle">
Seo Title</label>
<%= Html.TextBox("seoTitle", page.SeoTitle)%>
<input type="submit" value="Generate Seo Title" name="submitButton" />
</div>
sumber
Jawaban:
Saya pikir adalah bug di MVC. Saya bergumul dengan masalah ini selama berjam-jam hari ini.
Diberikan ini:
Tampilan dirender dengan model asli, mengabaikan perubahan. Jadi saya pikir, mungkin tidak suka saya menggunakan model yang sama, jadi saya coba seperti ini:
Dan masih tampilan render dengan model aslinya. Yang aneh adalah, ketika saya meletakkan breakpoint dalam tampilan dan memeriksa modelnya, nilainya berubah. Tetapi aliran respons memiliki nilai-nilai lama.
Akhirnya saya menemukan pekerjaan yang sama yang Anda lakukan:
Bekerja seperti yang diharapkan.
Saya tidak berpikir ini adalah "fitur", bukan?
sumber
Memperbarui:
View()
dari tindakan POST. Gunakan PRG sebagai gantinya dan alihkan ke GET jika aksinya berhasil.View()
dari tindakan POST, melakukannya untuk validasi form, dan melakukannya dengan cara MVC dirancang menggunakan dibangun di pembantu. Jika Anda melakukannya dengan cara ini maka Anda tidak perlu menggunakan.Clear()
ModelState
karena Anda tidak boleh menggunakannya.Jawaban lama:
ModelState di MVC digunakan terutama untuk menggambarkan keadaan objek model sebagian besar berkaitan dengan apakah objek itu valid atau tidak. Tutorial ini harus menjelaskan banyak hal.
Umumnya Anda tidak perlu menghapus ModelState karena itu dikelola oleh mesin MVC untuk Anda. Menghapusnya secara manual dapat menyebabkan hasil yang tidak diinginkan saat mencoba mematuhi praktik terbaik validasi MVC.
Tampaknya Anda mencoba menyetel nilai default untuk judul. Ini harus dilakukan ketika objek model dibuat instance-nya (lapisan domain di suatu tempat atau di objek itu sendiri - ctor tanpa parameter), pada tindakan get sedemikian rupa sehingga ia turun ke halaman untuk pertama kalinya atau sepenuhnya pada klien (melalui ajax atau sesuatu) sehingga tampak seolah-olah pengguna memasukkannya dan kembali dengan koleksi formulir yang diposting. Beberapa cara pendekatan Anda menambahkan nilai ini pada penerimaan koleksi bentuk (dalam aksi POST // Ubah) yang menyebabkan perilaku aneh ini yang mungkin mengakibatkan
.Clear()
muncul untuk bekerja untuk Anda. Percayalah - Anda tidak ingin menggunakan clear. Cobalah salah satu ide lainnya.sumber
Jika Anda ingin menghapus nilai untuk bidang individu, saya menemukan teknik berikut berguna.
Catatan: Ubah "Kunci" ke nama bidang yang ingin Anda setel ulang.
sumber
Nah, ModelState pada dasarnya memegang Status model saat ini dalam hal validasi, yang dimilikinya
ModelErrorCollection: Mewakili kesalahan saat model mencoba mengikat nilai. ex.
atau seperti parameter di ActionResult
ValueProviderResult : Simpan detail tentang percobaan pengikatan ke model. ex. AttemptedValue, Culture, RawValue .
Metode Clear () harus digunakan dengan hati-hati karena dapat menyebabkan hasil yang tidak diharapkan. Dan Anda akan kehilangan beberapa properti bagus dari ModelState seperti AttemptedValue, ini digunakan oleh MVC di latar belakang untuk mengisi kembali nilai formulir jika terjadi kesalahan.
sumber
Saya memiliki contoh di mana saya ingin memperbarui model formulir penjumlahan, dan tidak ingin 'Redirect To Action' karena alasan performanace. Nilai sebelumnya dari bidang tersembunyi dipertahankan pada model saya yang diperbarui - menyebabkan semua jenis masalah !.
Beberapa baris kode segera mengidentifikasi elemen dalam ModelState yang ingin saya hapus (setelah validasi), jadi nilai baru digunakan dalam bentuk: -
sumber
Banyak dari kita tampaknya telah digigit oleh ini, dan meskipun alasan ini terjadi masuk akal, saya membutuhkan cara untuk memastikan bahwa nilai pada Model saya ditampilkan, dan bukan ModelState.
Beberapa telah menyarankan
ModelState.Remove(string key)
, tetapi tidak jelas apa yangkey
seharusnya, terutama untuk model bersarang. Berikut adalah beberapa metode yang saya temukan untuk membantu hal ini.The
RemoveStateFor
Metode akan mengambilModelStateDictionary
, Model, dan ekspresi untuk properti yang diinginkan, dan menghapusnya.HiddenForModel
dapat digunakan dalam Tampilan Anda untuk membuat bidang input tersembunyi hanya menggunakan nilai dari Model, dengan terlebih dahulu menghapus entri ModelState-nya. (Ini dapat dengan mudah diperluas untuk metode ekstensi helper lainnya).Panggil dari pengontrol seperti ini:
atau dari tampilan seperti ini:
Ini digunakan
System.Web.Mvc.ExpressionHelper
untuk mendapatkan nama properti ModelState.sumber
Saya ingin memperbarui atau mengatur ulang nilai jika tidak cukup memvalidasi, dan mengalami masalah ini.
Jawaban mudahnya, ModelState.Remove, adalah .. bermasalah .. karena jika Anda menggunakan pembantu Anda tidak benar-benar tahu namanya (kecuali Anda tetap berpegang pada konvensi penamaan). Kecuali mungkin Anda membuat fungsi yang baik Anda kustom dapat digunakan oleh pembantu dan pengontrol Anda untuk mendapatkan nama.
Fitur ini seharusnya diimplementasikan sebagai opsi pada helper, di mana secara default tidak melakukan ini, tetapi jika Anda ingin input yang tidak diterima untuk ditampilkan kembali Anda bisa mengatakannya.
Tapi setidaknya saya mengerti masalahnya sekarang;).
sumber
Remove()
kunci yang benar.Mengerti pada akhirnya. ModelBinder Kustom saya yang tidak terdaftar dan melakukan ini:
Jadi sesuatu yang dilakukan oleh pengikatan model default pasti menyebabkan masalah. Tidak yakin apa, tetapi masalah saya setidaknya sudah diperbaiki sekarang karena pengikat model khusus saya sedang terdaftar.
sumber
Secara umum, ketika Anda menemukan diri Anda berjuang melawan praktik standar kerangka kerja, inilah saatnya untuk mempertimbangkan kembali pendekatan Anda. Dalam hal ini, perilaku ModelState. Misalnya, ketika Anda tidak menginginkan status model setelah POST, pertimbangkan pengalihan ke get.
DIEDIT untuk menjawab komentar budaya:
Inilah yang saya gunakan untuk menangani aplikasi MVC multi-budaya. Pertama subkelas pengendali rute:
Dan inilah cara saya mengatur rute. Setelah membuat rute, saya menambahkan subagen saya (example.com/subagent1, example.com/subagent2, dll) lalu kode budaya. Jika yang Anda butuhkan hanyalah budaya, cukup hapus subagen dari penangan rute dan rute.
sumber
Nah, ini sepertinya berfungsi di Halaman Razor saya dan bahkan tidak pernah melakukan perjalanan pulang pergi ke file .cs. Ini adalah cara html lama. Mungkin berguna.
sumber