【ASP.net MVC】自訂 Model 驗證屬性 — 資料驗證(4)

【ASP.net MVC】自訂 Model 驗證屬性 — 資料驗證(4)
在做資料驗證的時候不會遇到剛好內建的驗證方式,我們這時候通常都會利用正則表示式來實作我們所需要的資料驗證,但是這樣的欄位一個或兩個都還覺得簡單,要修改也只需要修改那一兩個,但是如果這個驗證套用到多次,而且又有不同的類別檔的時候呢?或是系統執行一段時間後,你還記得有哪些地方套用了這個驗證嗎?我想應該不太可能有人有這麼好的記性...
所以MVC提供了讓你擴充自己所需要的資料驗證!要如何實作呢,請看倌們往下看!
先說明一下本篇的案例好了,若其他需求請自行修改!
在小弟的網站上,需要用戶輸入手機號碼,內建的phone的驗證似乎沒有效果,所以只好動手寫一個出來了!

在做資料驗證的時候不會遇到剛好內建的驗證方式,我們這時候通常都會利用正則表示式來實作我們所需要的資料驗證,但是這樣的欄位一個或兩個都還覺得簡單,要修改也只需要修改那一兩個,但是如果這個驗證套用到多次,而且又有不同的類別檔的時候呢?或是系統執行一段時間後,你還記得有哪些地方套用了這個驗證嗎?我想應該不太可能有人有這麼好的記性...

所以MVC提供了讓你擴充自己所需要的資料驗證!要如何實作呢,請看倌們往下看!

先說明一下本篇的案例好了,若其他需求請自行修改!

在小弟的網站上,需要用戶輸入手機號碼,內建的phone的驗證似乎沒有效果,所以只好動手寫一個出來了!

 

首先,我們需要新增一個CellPhone的Class檔案,來放置我們驗證的程式碼

【放置的資料夾】->(右鍵)【加入】->【類別】

image

 

檔案新增完畢後,需要繼承ValidationAttribute這個類別,才會是一個驗證的Attribute,並且override IsValid的Method

public class CellPhone : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        //not input
        if (value == null)
            return true;
        //has input
        if (value is String)
            //手機應該都是開頭,並且有10碼,所以利用正則表示式來表示就是這樣
            //IsMatch本身就是bool的回傳值,所以利用直接回傳這個值,就可以表示是否已經通過驗證
            return Regex.IsMatch(value.ToString(), "^09[0-9]{8}");
        else
            return true;
    }
}

如此一來這個屬性就會在Server端的驗證了,那Clinet端呢?

Client端需要靠JavaScript的方式來做驗證,另外也需要IClientValidatable介面來幫忙

繼承了這個介面後,我們要實作GetClientValidationRules這個Method

所以在剛剛的程式碼後面加上了這一段

!注意:ValidationType中的值,必須要是小寫的字母否則會出錯

               Rule.ValidationParameters["input"] = "09XXXXXXXX";則會在Html加上一個data-val-cellphone-input="09XXXXXXXX"這樣的屬性

public IEnumerable GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    ModelClientValidationRule Rule = new ModelClientValidationRule
    {
        //這個屬性的值必須要是小寫內容,否則會出錯
        ValidationType = "cellphone",
        ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
    };
    Rule.ValidationParameters["input"] = "09XXXXXXXX";
    yield return Rule;
}

 

public class CellPhone : ValidationAttribute, IClientValidatable
    {
        public override bool IsValid(object value)
        {
            //not input
            if (value == null)
                return true;
            //has input
            if (value is String)
                return Regex.IsMatch(value.ToString(), "^09[0-9]{8}");
            else
                return true;
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            ModelClientValidationRule Rule = new ModelClientValidationRule
            {
                ValidationType = "cellphone",
                ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
            };
            Rule.ValidationParameters["input"] = "09XXXXXXXX";
            yield return Rule;
        }
    }
}

新增了這一段程式碼後,我們需要放置一段JavaScript語法在前端為我們做驗證,而這段JavaScript的邏輯規則是將您複寫的IsValid這個Method中的C#語法轉換成JavaScript語法,完成後在將這段JavaScript語法再掛載到前端頁面上就可以完成了!

!注意:在掛載時需要注意到一點就是必須掛載在jquery.validate.js以及jquery.validate.unobtrusive.js後面,否則JavaScript會出錯!

$.validator.addMethod("cellphone", function (value, element, param) {
    if (value == false) return true;//not input
	return (/^09[0-9]{8}/.test(value)) //has input
});
$.validator.unobtrusive.adapters.addSingleVal("cellphone", "input");

 

這樣子,手機驗證在前端以及後端的Server都可以做到驗證了!若這個驗證套用到多個地方,也只需要改變JavaScript以及這個驗證的Attribute就可以囉!

 

 

【參考資料】

http://www.youtube.com/watch?v=tjPOTB41CkU&feature=youtu.be

http://mvc.tw/Event/2012/7/14

http://demo.tc/Post/688

 


 

大家好我是饅頭,希望大家喜歡我的文章

如果有錯誤的地方請不吝指教 ^_^