ASP.NET MVC3 自訂驗證規則 帳號不能註冊為 demoshop !(使用 AddSingleVal 方法)
- 2011-07-11
- 15635
- 0
- ASP.NET MVC3 驗證介紹實作與擴充
這次來到第二種自訂驗證的方法 SingleVal,其實這裡說的這些都是屬於前端驗證的方法,後端是很隨意的 讓我們來假設一下,今天 demo小鋪開放註冊會員,但是不希望有任何人註冊有關於 demo 這個名字,如果使用上一篇文章介紹的 AddBool 方式來寫,當哪一天要改成 「demoshop」 或是 「demo小鋪」的時候就會有很多地方要改,但是明明驗證邏輯是一樣的只是驗證的比對值不同,所以可以利用所謂的 AddSingleVal 方法來擴充驗證,要比對的值使用參數傳入,驗證的邏輯則是固定,這樣子就可以運用到多個情境,以下就是介紹
依序前文的範例,這次我們也同樣在 ValidateAttribute 資料夾中建立一個新類別,取名為 【NoIsAttribute】
這次我們已經知道需要驗證前端了,因此直接繼承 ValidationAttribute 和 IClientValidatable ,Code會長這樣
public class NoIsAttribute : ValidationAttribute, IClientValidatable { /// <summary> /// 禁止輸入的值 /// </summary> public string Input { get; set; } //因為此驗證不可能不輸入要禁止的值,所以利用建構式來強迫輸入 public NoIsAttribute(string input) { this.Input = input; } public override bool IsValid(object value) { //要不要輸入與此驗證無關 if (value == null) return true; //如果輸入的值是字串才做判斷 if (value is string) { //輸入值與欄位值相同就報錯 if (Input.Contains(value.ToString())) return false; } return true; } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { ModelClientValidationRule rule = new ModelClientValidationRule { ValidationType = "nois", ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()) }; //此參數一定要是小寫! rule.ValidationParameters["input"] = Input; yield return rule; } }
rule.ValidationParameters的名稱一定要是小寫
再來實作前端的 JS
<script type="text/javascript"> $.validator.addMethod("nois", function (value, element, param) { if (value == false) { return true; } if (value.indexOf(param) != -1) { return false; } else { return true; } }); $.validator.unobtrusive.adapters.addSingleVal("nois", "input"); </script>
邏輯與後端驗證相同,只是寫法改成了 javascript ,要注意的是因為此類型的驗證是有參數的,所以參數要註冊進去因此這次使用了addSingleVal 方法,第一個參數就是此 Method 名,第二個參數需要與後端的 rule.ValidationParameters名稱相同。
接者前進到 RegisterModel Class 將 UserName 欄位的驗證改成如下(為了方便測試)
[Required] [NoIs("demo",ErrorMessage="請使用別的名稱")] [Display(Name = "User name")] public string UserName { get; set; }
再來就是到註冊頁面測試效果囉
初步的擴充完成,但立刻會遇到一個問題,是否可以一次判斷多個禁止的值,這當然是可以完成的,而且要用習慣來完成,什麼叫做習慣?通常大家應該都很習慣多個值用逗點分隔吧,因此就利用這習慣來實作多個禁止值的擴充吧。
回到 NoIsAttribute 調整 Code
public class NoIsAttribute : ValidationAttribute, IClientValidatable { /// <summary> /// 禁止輸入的值 /// </summary> public string[] Input { get; set; } //因為此驗證不可能不輸入要禁止的值,所以利用建構式來強迫輸入 public NoIsAttribute(string input) { //檢查是否有包含分隔符號 if (input.IndexOf(",") > -1) //有的話就切吧 this.Input = input.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); else //沒有的話就新增一個字串陣列塞過去 this.Input = new string[] { input }; } public override bool IsValid(object value) { //要不要輸入與此驗證無關 if (value == null) return true; //如果輸入的值是字串才做判斷 if (value is string) { //輸入值與欄位值相同就報錯 if (Input.Contains(value.ToString())) return false; } return true; } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { ModelClientValidationRule rule = new ModelClientValidationRule { ValidationType = "nois", ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()) }; //此參數一定要是小寫! rule.ValidationParameters["input"] = string.Join(",", Input); yield return rule; } }
前端驗證也需要調整
<script type="text/javascript"> $.validator.addMethod("nois", function (value, element, param) { if (value == false) { return true; } var validateState = true; var paramarr = param.split(','); $.each(paramarr, function (i, n) { if (value==n) { validateState = false; return; } }); return validateState; }); $.validator.unobtrusive.adapters.addSingleVal("nois", "input"); </script>
再前往 RegisterModel Class 將 UserName 欄位的驗證改成如下
[Required] [NoIs("demo,小鋪",ErrorMessage="請使用別的名稱")] [Display(Name = "User name")] public string UserName { get; set; }
然後您就可以到註冊頁測試了,當使用者打了 「demo」 或是 「小鋪」 就會被限制囉,當然因為這驗證已經將變數抽了出來,所以如果需要套用在別的屬性上面也相當的容易,比如現在也將 Email 加上不可以輸入(123@123.com)的驗證
[Required] [DataType(DataType.EmailAddress)] [NoIs("123@123.com", ErrorMessage = "Email太假")] [Display(Name = "Email")] public string Email { get; set; }
可以輸入參數以後彈性的確是增加了許多,不過擴充驗證規則還沒寫完哩,下一篇將介紹另一種大小值的驗證擴充法。
回應討論