demoshop

demo, trying to be the best_

版本
3

ASP.NET MVC3 提供了一個 IValidatableObject 介面,提供類別層級的驗證,因此很適合在這裡寫入複合的商業邏輯,你可能會想使用之前介紹過的 IClientValidatable 自定驗證來達成,但實作上就會發現 IClientValidatable 自定驗證無法寫出同時需要考慮到多個屬性欄位的驗證邏輯,因此當你的驗證是要同時考慮兩個以上的屬性欄位,IValidatableObject 就是一個相當不錯的驗證方式。

demo廢言為了測試方便,這次將 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;
}

demo廢言當我們寫完了驗證邏輯開開心心的跑去前端測試時,你會很明確的看到,在 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);
}

demo廢言  ASP.NET MVC3 驗證相關的介紹大致到此篇為止,對於此系列文如果有任何建議或批評指教,歡迎留言告知。

回應討論