ASP.NET MVC3 自訂驗證規則 撰寫類別層級的驗證
- 2011-08-02
- 18709
- 0
- ASP.NET MVC3 驗證介紹實作與擴充
- 版本
- 3
ASP.NET MVC3 提供了一個 IValidatableObject 介面,提供類別層級的驗證,因此很適合在這裡寫入複合的商業邏輯,你可能會想使用之前介紹過的 IClientValidatable 自定驗證來達成,但實作上就會發現 IClientValidatable 自定驗證無法寫出同時需要考慮到多個屬性欄位的驗證邏輯,因此當你的驗證是要同時考慮兩個以上的屬性欄位,IValidatableObject 就是一個相當不錯的驗證方式。
為了測試方便,這次將 RegisterModel 的驗證都抽掉,並且增加兩個屬性
public string UserName { get; set; } public string Email { get; set; } public string Password { get; set; } public string ConfirmPassword { get; set; } [Display(Name = "報名人數")] public int RegisterCount { get; set; } [Display(Name = "名額限制")] public int Quota { get; set; }
這次要增加的是 Class Level 的驗證所以就讓 RegisterModel 繼承 IValidatableObject 介面,此介面只有一個方法需要實作
public class RegisterModel : IValidatableObject { public string UserName { get; set; } public string Email { get; set; } public string Password { get; set; } public string ConfirmPassword { get; set; } [Display(Name = "報名人數")] public int RegisterCount { get; set; } [Display(Name = "名額限制")] public int Quota { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { throw new NotImplementedException(); } }
假設今天我們的邏輯是單次報名的人數不得超過名額限制,那就直接很自然的寫下去
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (RegisterCount > Quota) { yield return new ValidationResult("報名人數已經超過名額限制", new string[] { "RegisterCount" }); } }
當然驗證不會只有一個,如果有多個邏輯可以改用下列寫法
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { var results = new List<ValidationResult>(); if (RegisterCount > Quota) { results.Add(new ValidationResult("報名人數已經超過名額限制", new string[] { "RegisterCount" })); } if (RegisterCount>3) { results.Add(new ValidationResult("單次最多報名三位學員", new string[] { "RegisterCount" })); } return results; }
當我們寫完了驗證邏輯開開心心的跑去前端測試時,你會很明確的看到,在 Validate 內寫的商業邏輯並不會觸發前端驗證,是屬於後端的驗證(所以文章一開始 demo 說為了測試方便把之前定義的驗證都拿掉,主要就是避免在前端被擋住),當然不管你是使用了 IValidatableObject 還是 IClientValidatable,一定要記得呼叫 ModelState.IsValid 方法,來確保資料是驗證通過的,以下就做個簡單範例。
[HttpPost] public ActionResult Register(RegisterModel model) { //檢查資料是否驗證通過 if (ModelState.IsValid) { //資料通過驗證執行項目 try { //真正執行寫入資料庫的方法 //執行成功回到列表頁 return View("Index"); } catch (Exception) { //發生例外 //記錄 Log 或是任何例外處理 } } //資料寫入失敗導回資料頁 return View(model); }
ASP.NET MVC3 驗證相關的介紹大致到此篇為止,對於此系列文如果有任何建議或批評指教,歡迎留言告知。
回應討論