ASP.NET MVC3 自訂驗證規則 帳號不能註冊為 demoshop !(使用 AddSingleVal 方法)
- 2011-07-11
- 18037
- 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; }

可以輸入參數以後彈性的確是增加了許多,不過擴充驗證規則還沒寫完哩,下一篇將介紹另一種大小值的驗證擴充法。








Roslyn 魔法工坊:打造你的 Source Generator [2025-12-20]開課 共7H
回應討論