asp.net mvc3 數據驗證(三)—自定義數據注解


        前兩節講的都是asp.net mvc3預先設定的數據注解,但是系統自由的數據注解肯定不適合所有的場合,所以有時候我們需要自定義數據注解。
        自定義數據注解有兩種,一種是直接寫在模型對象中,這樣做的好處是驗證時只需要關心一種模型對象的驗證邏輯,缺點也是顯而易見的,那就是不能重用。
                                            還有一種是封裝在自定義的數據注解中,優點是可重用,缺點是需要應對不同類型的模型。
        現在我們以封裝在自定義數據注解中的方法為例看下如何在asp.net mvc3中自定義數據注解以及使用。
 
一、自定義屬性級別的驗證
        首先,所有的數據注解都應繼承於 System.ComponentModel.DataAnnotations命名空間中的 ValidationAttribute類。
            重寫其 protected virtual ValidationResult IsValid(object value, ValidationContext validationContext);
例如:
        我們需要寫一個UserName不能超過10個字母的數據注解(你可能會說這不是有的 StringLength么,好吧,僅以此為例,我真沒想到其他的需要自定義數據注解的好例子)。
        (1)新建一個類 MaxLengthAttribute,代碼如下:
    public class MyMaxLengthAttribute : ValidationAttribute
    {
        private readonly int MaxLength;
 
        public MyMaxLengthAttribute(int maxLength)
        {
            MaxLength = maxLength;
        }
 
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            string content = value.ToString();
            if (content.Length > MaxLength)
            {
                return new ValidationResult("輸入的字符太多了!^_^");
            }
            return ValidationResult.Success;
            //return base.IsValid(value, validationContext);
        }
        第二步就是像正常使用asp.net自帶的數據注解一樣使用,如:
        
        [Required(ErrorMessageResourceType=typeof(ErrorMessage),ErrorMessageResourceName="UserRequire")]
        [Display(Name = "用戶名")]
        [MyMaxLengthAttribute(10)]
        [Remote("CheckUserName","Account", HttpMethod="POST")]
        public string UserName { get; set; }
        好了,只需要這樣簡單的兩步就可以實現了。

驗證結果:
        對於自定義的數據注解由於是繼承於 System.ComponentModel.DataAnnotations命名空間中的 ValidationAttribute類,所以它的一些屬性也可以使用,比如ErrorMessage,如:
        [Required(ErrorMessageResourceType=typeof(ErrorMessage),ErrorMessageResourceName="UserRequire")]
        [Display(Name = "用戶名")]
        [MyMaxLengthAttribute(10,ErrorMessage="{0}字數太多")]
        [Remote("CheckUserName","Account", HttpMethod="POST")]
        public string UserName { get; set; }
        需要注意的是,自定義的數據注解不支持客戶端驗證,所有的數據需要提交之后再服務端驗證,所以如果要同時實現客戶端驗證需要自己寫js驗證。
 
但是這樣的驗證有一個問題,就是默認的驗證信息不能實現直接顯示Display Name,所以需要如下更改:
    public class MyMaxLengthAttribute : ValidationAttribute
    {
        private readonly int MaxLength;
 
        public MyMaxLengthAttribute(int maxLength ):base("{0}的字符太多了!")
        {
            MaxLength = maxLength;
        }
 
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            string content = value.ToString();
            if (content.Length > MaxLength)
            {
                //return new ValidationResult("輸入的字符太多了!^_^");
                string errorMessage = FormatErrorMessage(validationContext.DisplayName); 
                return new ValidationResult(errorMessage);
            }
            return ValidationResult.Success;
            //return base.IsValid(value, validationContext);
        }
    }
 
 驗證結果:

 
二、自定義Model級別的驗證(IValidatableObject)
        這個接口是為了實現Model的自驗證(self-validating)的,是asp.net mvc3 新增的驗證特性。這個特性和普通數據注解的區別是普通數據注解僅僅只能驗證Model的一個屬性,而實現了IValidatableObject接口的自驗證則在Model的級別來驗證,比如驗證Model的幾個屬性之間的關系等。
        例如,我要驗證兩次輸入的密碼相同(好吧,我又把系統自帶的驗證再寫一遍)。
        (1)首先,要將需要驗證的Model實現IValidatableObject接口。
     public class RegisterModel : IValidatableObject
        (2)在Model中實現 Validate方法:
        public IEnumerable<ValidationResult> Validate(ValidationContext validationContent)
        {
            if (Password != ConfirmPassword)
            {
                yield return new ValidationResult("兩次輸入的密碼不同!", new[] { "Password" });
            }
        }

 

        這個方法在提交Model時會自動驗證兩次輸入的密碼是否相同,如果不同則會提示,如下:

 
注意:1、自驗證只能把方法寫在需要驗證的Model中,所以這種自驗證的代碼無法重用;
            2、自驗證的返回值是 IEnumerable<ValidationResult>,而不是 ValidationResult,所以返回值可以不止一個驗證錯誤。
            3、Validate方法沒有傳入value參數,也就是意味着Validate方法可以直接訪問Model中的屬性值。
            4、返回值使用的是yield return來構建枚舉返回值,第二個參數是指定錯誤信息綁定的屬性,因為是string數組,所以可以關聯多個屬性。
 
順便把練習用的源碼分享了,Model部分主要在RegisterModel,下載請點擊: http://pan.baidu.com/share/link?shareid=143863&uk=4044128861


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM