Bagaimana cara menggunakan anotasi data untuk melakukan validasi bersyarat pada model?
Misalnya, katakanlah kita memiliki model berikut (Orang dan Senior):
public class Person
{
[Required(ErrorMessage = "*")]
public string Name
{
get;
set;
}
public bool IsSenior
{
get;
set;
}
public Senior Senior
{
get;
set;
}
}
public class Senior
{
[Required(ErrorMessage = "*")]//this should be conditional validation, based on the "IsSenior" value
public string Description
{
get;
set;
}
}
Dan tampilan berikut:
<%= Html.EditorFor(m => m.Name)%>
<%= Html.ValidationMessageFor(m => m.Name)%>
<%= Html.CheckBoxFor(m => m.IsSenior)%>
<%= Html.ValidationMessageFor(m => m.IsSenior)%>
<%= Html.CheckBoxFor(m => m.Senior.Description)%>
<%= Html.ValidationMessageFor(m => m.Senior.Description)%>
Saya ingin menjadi bidang persyaratan bersyarat properti "Senior.Description" berdasarkan pemilihan kelayakan "IsSenior" (benar -> wajib). Bagaimana cara menerapkan validasi bersyarat dalam ASP.NET MVC 2 dengan anotasi data?
c#
asp.net-mvc
forms
validation
Peter Stegnar
sumber
sumber
Senior
objek selalu senior, jadi mengapa IsSenior dapat palsu dalam kasus itu. Jangan Anda hanya perlu properti 'Person.Senior' menjadi nol ketikaPerson.IsSenior
salah. Atau mengapa tidak menerapkanIsSenior
properti sebagai berikut:bool IsSenior { get { return this.Senior != null; } }
.Jawaban:
Ada cara yang jauh lebih baik untuk menambahkan aturan validasi bersyarat di MVC3; minta model Anda mewarisi
IValidatableObject
dan mengimplementasikanValidate
metode:Baca lebih lanjut di Memperkenalkan ASP.NET MVC 3 (Pratinjau 1) .
sumber
ModelState.IsValid
- tidak menelepon Validasi langsungSaya telah memecahkan ini dengan menangani kamus "ModelState" , yang berisi oleh controller. Kamus ModelState mencakup semua anggota yang harus divalidasi.
Ini solusinya:
Jika Anda perlu menerapkan validasi bersyarat berdasarkan pada beberapa bidang (mis. Jika A = true, maka B diperlukan), sambil mempertahankan pesan kesalahan tingkat properti (ini tidak berlaku untuk validator kustom yang ada di level objek) Anda dapat mencapai ini dengan menangani "ModelState", dengan hanya menghapus validasi yang tidak diinginkan darinya.
... Di beberapa kelas ...
... kelas berlanjut ...
... Dalam beberapa aksi pengontrol ...
...
Dengan ini kami mencapai validasi bersyarat, sambil membiarkan semuanya tetap sama.
MEMPERBARUI:
Ini adalah implementasi terakhir saya: Saya telah menggunakan antarmuka pada model dan atribut tindakan yang memvalidasi model yang mengimplementasikan antarmuka tersebut. Antarmuka mengatur metode Validasi (ModelStateDictionary modelState). Atribut pada tindakan hanya memanggil Validasi (modelState) pada IValidatorSomething.
Saya tidak ingin mempersulit jawaban ini, jadi saya tidak menyebutkan detail implementasi akhir (yang, pada akhirnya, masalah dalam kode produksi).
sumber
Saya memiliki masalah yang sama kemarin tetapi saya melakukannya dengan cara yang sangat bersih yang berfungsi untuk validasi sisi klien dan sisi server.
Kondisi: Berdasarkan nilai properti lain dalam model, Anda ingin membuat properti lain diperlukan. Ini kodenya
Di sini PropertyName adalah properti yang Anda inginkan untuk membuat kondisi Anda DesiredValue adalah nilai khusus dari PropertyName (properti) yang harus divalidasi oleh properti Anda yang lain.
Katakanlah Anda memiliki yang berikut ini
Akhirnya tetapi bukan yang terakhir, daftarkan adaptor untuk atribut Anda sehingga dapat melakukan validasi sisi klien (saya taruh di global.asax, Application_Start)
sumber
Saya telah menggunakan nuget menakjubkan ini yang melakukan anotasi dinamis ExpressiveAnnotations
Anda dapat memvalidasi logika apa pun yang dapat Anda impikan:
sumber
Anda dapat menonaktifkan validator secara kondisional dengan menghapus kesalahan dari ModelState:
sumber
Terima kasih Merritt :)
Saya baru saja memperbarui ini ke MVC 3 jika ada orang yang merasa berguna: Validasi Bersyarat dalam ASP.NET MVC 3 .
sumber
Sekarang ada kerangka kerja yang melakukan validasi bersyarat ini (di antara validasi anotasi data berguna lainnya) di luar kotak: http://foolproof.codeplex.com/
Secara khusus, lihat validator [RequiredIfTrue ("IsSenior")]. Anda meletakkannya langsung di properti yang ingin divalidasi, sehingga Anda mendapatkan perilaku kesalahan validasi yang diinginkan terkait dengan properti "Senior".
Ini tersedia sebagai paket NuGet.
sumber
Anda perlu memvalidasi pada tingkat Orang, bukan pada tingkat Senior, atau Senior harus memiliki referensi ke Orang induknya. Menurut saya, Anda memerlukan mekanisme validasi diri yang mendefinisikan validasi pada Person dan bukan pada salah satu propertinya. Saya tidak yakin, tapi saya pikir DataAnnotations tidak mendukung hal ini. Apa yang dapat Anda lakukan buat milik Anda
Attribute
yang berasal dariValidationAttribute
yang dapat didekorasi di tingkat kelas dan selanjutnya buat validator khusus yang juga memungkinkan validator tingkat-kelas itu untuk dijalankan.Saya tahu Blok Aplikasi Validasi mendukung validasi diri di luar kotak, tetapi VAB memiliki kurva belajar yang cukup curam. Namun demikian, inilah contoh menggunakan VAB:
sumber
Saya memiliki masalah yang sama, memerlukan modifikasi atribut [Wajib] - membuat bidang diperlukan dalam ketergantungan http request. Solusinya mirip dengan jawaban Dan Hunex, tetapi solusinya tidak bekerja dengan benar (lihat komentar). Saya tidak menggunakan validasi yang tidak mencolok, cukup MicrosoftMvcValidation.js di luar kotak. Ini dia. Terapkan atribut khusus Anda:
Maka Anda perlu mengimplementasikan penyedia kustom Anda untuk menggunakannya sebagai adaptor di global.asax Anda
Dan modifikasi global.asax Anda dengan sebuah garis
dan ini dia
Keuntungan utama bagi saya adalah bahwa saya tidak perlu kode validator klien kustom seperti dalam kasus validasi yang tidak mencolok. ini berfungsi seperti [Diperlukan], tetapi hanya dalam kasus yang Anda inginkan.
sumber
DataAnnotationsModelValidator
adalah apa yang perlu saya lihat. Terima kasih.Lihatlah Pengesahan Bersyarat Simon Ince di MVC .
Saya sedang mengerjakan proyek contohnya sekarang.
sumber
Penggunaan umum untuk penghapusan kesalahan kondisional dari Model State:
Contoh:
Dalam contoh Anda, pertahankan semuanya apa adanya dan tambahkan logika yang disarankan untuk Tindakan Pengendali Anda. Saya mengasumsikan ViewModel Anda yang diteruskan ke action controller memiliki objek Person dan Senior Person dengan data yang terisi di dalamnya dari UI.
sumber
Saya menggunakan MVC 5 tetapi Anda dapat mencoba sesuatu seperti ini:
Dalam kasus Anda, Anda akan mengatakan sesuatu seperti "IsSenior == true". Maka Anda hanya perlu memeriksa validasi pada tindakan posting Anda.
sumber