zoukankan      html  css  js  c++  java
  • 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

    移步我最优惠网,尽享全网折扣商品。

    PS:我最优惠网是一个汇集京东、天猫、Amazon等知名电商优惠活动和商品的网站,更精明的剁手,从我最优惠开始

  • 相关阅读:
    python json模块(15)
    python random模块(14)
    python time模块(13)
    python sys模块(12)
    python zip函数(11)
    python递归函数(10)
    python 浅拷贝和深拷贝(9)
    python is 和 == 区别(8)
    python 可变数据类型和不可变数据类型(7)
    python局部变量和全局变量(6)
  • 原文地址:https://www.cnblogs.com/zhangkai2237/p/2814825.html
Copyright © 2011-2022 走看看