【C#】创建自定义的验证特性类

原理:

  根据反射、扩展方法、特性、抽象类及方法  等基础知识,搭建属于我们自己的实体类自定义验证特性类

1、创建抽象特性类(AbstractValidateAttribute)及Validate方法【因为是特性类所以要继承自Attribute】

//定义抽象类,创建抽象方法,该类继承自Attribute
    public abstract class AbstractValidateAttribute:Attribute
    {
        //定义抽象方法,各个子类继承并实现该方法
        public abstract bool Validate(Object value);
    }

 

2、创建具体的自定义验证特性类

  a、长度验证特性类,继承自AbstractValidateAttribute,并实现他的方法

//整型长度验证
    //限制该特性,只能用于属性
    [AttributeUsage(AttributeTargets.Property)]
    public class LongAttribute : AbstractValidateAttribute
    {
        private long _Long=0;  //私有字段  用来验证实体类属性的长度是否合适
        public LongAttribute(long Long)
        {
            this._Long = Long;
        }
        //判断长度的方法,实体类属性的值长度应该和特性定义的长度一致
        public override bool Validate(object value)
        {
            return value != null && (long)(value.ToString().Length) == _Long;
        }
    }

  b、必填特性类,同上

//非空验证特性
    //限制该特性,只能用于属性
    [AttributeUsage(AttributeTargets.Property)]
    public class RequiredAttribute : AbstractValidateAttribute
    {
        //验证方法实现
        public override bool Validate(object value)
        {
            return value != null && !string.IsNullOrWhiteSpace(value.ToString());
        }
    }

  c、字符串最大值,最小值特性类

//字符串长度范围验证
    //限制该特性,只能用于属性
    [AttributeUsage(AttributeTargets.Property)]
    public class StringLengAttribute : AbstractValidateAttribute
    {
        private int _Min; //定义最小值
        private int _Max; //定义最大值
        public StringLengAttribute(int Min,int Max)
        {
            this._Max = Max;
            this._Min = Min;
        }

        //验证字符串长度在合理的范围内
        public override bool Validate(object value)
        {
            return value != null
                && value.ToString().Length >= _Min
                && value.ToString().Length <= _Max;
        }
    }

  d、邮箱特性类

//Email验证
    //限制该特性,只能用于属性
    [AttributeUsage(AttributeTargets.Property)]
    public class EmailAttribute : AbstractValidateAttribute
    {
        public override bool Validate(object value)
        {
            //邮箱验证规则
            return Regex.IsMatch(value.ToString(), @"^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$");
        }
    }

  篇幅关系这里不再列举其他特性类

 

3、创建测试实体类Student,并在各个属性上添加自定义的特性

public class Student
    {
        [Required]
        public int Id { get; set; }
        [Long(11)]
        [Required]
        public string Phone { get; set; }
        [Required]
        [Email]
        public string Email { get; set; }
        [Required]
        [StringLeng(2,4)]
        public string StudentName { get; set; }
    }

 

4、编写扩展方法,实现Validate验证并返回验证结果bool值

//定义特性的扩展方法(扩展方法定义:静态类的静态方法,方法的参数需包含要扩展类的实例)
    public static class AttributeExtend
    {
        //参数里面this关键字 特别重要,加了this,可以直接在实体类的扩展方法里找到Validate,否则看不到
        /// <summary>
        /// 扩展方法(用来验证实体类的各个参数是否符合预期)
        /// </summary>
        /// <typeparam name="T">目标类</typeparam>
        /// <param name="t">目标类的实例化对象</param>
        /// <returns>验证结果true或false</returns>
        public static bool Validate<T>(this T t)
        {
            Type type = t.GetType();  //获取目标类的类型(实际就是传进来的实体类对象)
            int ss = type.GetProperties().Length;
            foreach (var prop in type.GetProperties())//获取实体类对象的所有属性集合,循环取出
            {
                if (prop.IsDefined(typeof(AbstractValidateAttribute), true))  //这里传入的是抽象类和true,这样就可以我们写的所有验证attribute类都包含进来(Email、Long、Required等)  
                {
                    object values = prop.GetValue(t);  //获取当前属性的值
                    //因为prop已经是确定的属性了,所以直接GetCustomAttributes即可[循环是因为每个属性上可能加了多个特性]
                    foreach (AbstractValidateAttribute attribute in prop.GetCustomAttributes(typeof(AbstractValidateAttribute), true))
                    {
                        //还是因为一个属性上,可能有多个特性限定,所以这里判断如果失败,直接返回false,直到所有循环处理完,如果没有false,说明所有验证成功,返回true
                        if (!attribute.Validate(values))
                        {
                            return false;
                        }
                    }  

                }
            }
            return true;
        }
    }

 

5、测试

//实战实体类验证
            Student student = new Student
            {
                Id = 1,
                StudentName = "张三张三张三",
                Email="22@qq.com",
                Phone="12345678900"
            };

            bool result = student.Validate();
            Console.WriteLine(result);
               

 

 

6、调用结果:

可以看到验证结果为false;  原因是:学生姓名超过定义的长度范围了

 

 

posted @ 2022-08-22 14:34  狼窝窝  阅读(379)  评论(0)    收藏  举报