ASP.NET MVC3 自訂驗證規則 帳號不能註冊為 demoshop !(使用 AddSingleVal 方法)
- 2011-07-11
- 18051
- 0
- ASP.NET MVC3 驗證介紹實作與擴充
這次來到第二種自訂驗證的方法 SingleVal,其實這裡說的這些都是屬於前端驗證的方法,後端是很隨意的  讓我們來假設一下,今天 demo小鋪開放註冊會員,但是不希望有任何人註冊有關於 demo 這個名字,如果使用上一篇文章介紹的 AddBool 方式來寫,當哪一天要改成 「demoshop」 或是 「demo小鋪」的時候就會有很多地方要改,但是明明驗證邏輯是一樣的只是驗證的比對值不同,所以可以利用所謂的 AddSingleVal 方法來擴充驗證,要比對的值使用參數傳入,驗證的邏輯則是固定,這樣子就可以運用到多個情境,以下就是介紹
 讓我們來假設一下,今天 demo小鋪開放註冊會員,但是不希望有任何人註冊有關於 demo 這個名字,如果使用上一篇文章介紹的 AddBool 方式來寫,當哪一天要改成 「demoshop」 或是 「demo小鋪」的時候就會有很多地方要改,但是明明驗證邏輯是一樣的只是驗證的比對值不同,所以可以利用所謂的 AddSingleVal 方法來擴充驗證,要比對的值使用參數傳入,驗證的邏輯則是固定,這樣子就可以運用到多個情境,以下就是介紹
 依序前文的範例,這次我們也同樣在 ValidateAttribute 資料夾中建立一個新類別,取名為 【NoIsAttribute】
依序前文的範例,這次我們也同樣在 ValidateAttribute 資料夾中建立一個新類別,取名為 【NoIsAttribute】

 這次我們已經知道需要驗證前端了,因此直接繼承 ValidationAttribute 和 IClientValidatable ,Code會長這樣
這次我們已經知道需要驗證前端了,因此直接繼承 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的名稱一定要是小寫
rule.ValidationParameters的名稱一定要是小寫
 再來實作前端的 JS
再來實作前端的 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名稱相同。
邏輯與後端驗證相同,只是寫法改成了 javascript ,要注意的是因為此類型的驗證是有參數的,所以參數要註冊進去因此這次使用了addSingleVal 方法,第一個參數就是此 Method 名,第二個參數需要與後端的 rule.ValidationParameters名稱相同。
 接者前進到 RegisterModel Class 將 UserName 欄位的驗證改成如下(為了方便測試)
接者前進到 RegisterModel Class 將 UserName 欄位的驗證改成如下(為了方便測試)
[Required]
[NoIs("demo",ErrorMessage="請使用別的名稱")]
[Display(Name = "User name")]
public string UserName { get; set; }
 再來就是到註冊頁面測試效果囉
再來就是到註冊頁面測試效果囉

 初步的擴充完成,但立刻會遇到一個問題,是否可以一次判斷多個禁止的值,這當然是可以完成的,而且要用習慣來完成,什麼叫做習慣?通常大家應該都很習慣多個值用逗點分隔吧,因此就利用這習慣來實作多個禁止值的擴充吧。
初步的擴充完成,但立刻會遇到一個問題,是否可以一次判斷多個禁止的值,這當然是可以完成的,而且要用習慣來完成,什麼叫做習慣?通常大家應該都很習慣多個值用逗點分隔吧,因此就利用這習慣來實作多個禁止值的擴充吧。
 回到 NoIsAttribute 調整 Code
回到 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 欄位的驗證改成如下
再前往 RegisterModel Class 將 UserName 欄位的驗證改成如下
[Required]
[NoIs("demo,小鋪",ErrorMessage="請使用別的名稱")]
[Display(Name = "User name")]
public string UserName { get; set; }
 然後您就可以到註冊頁測試了,當使用者打了 「demo」 或是 「小鋪」 就會被限制囉,當然因為這驗證已經將變數抽了出來,所以如果需要套用在別的屬性上面也相當的容易,比如現在也將 Email 加上不可以輸入(123@123.com)的驗證
然後您就可以到註冊頁測試了,當使用者打了 「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
Roslyn 魔法工坊:打造你的 Source Generator [2025-12-20]開課 共7H
回應討論