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

之前讲过创建自定义验证的特性类:

传送门:https://www.cnblogs.com/yhnet/articles/16612729.html

这个Validate方法,只返回验证结果,并没有告诉我们到底是哪个验证出错了

这个pro版本继续利用特性及反射,对Validate方法做重载,在验证错误时,带出具体哪里出错的错误信息

 

1、创建获取描述信息的特性类

[AttributeUsage(AttributeTargets.All)]
    public class DescriptionAttribute:Attribute
    {
        //enum的描述信息
        public string _Description;
        public DescriptionAttribute(string description)
        {
            this._Description = description;
        }

    }

 

2、改造之前编写的EmailAttribute、LongAttribute、RequiredAttrubute、StringLengthAttribute类

//Email验证
    //限制该特性,只能用于属性
    [AttributeUsage(AttributeTargets.Property)]
    [Description("邮箱验证失败")]
    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_-]+)+$");
        }
    }


//整型长度验证
    //限制该特性,只能用于属性
    [AttributeUsage(AttributeTargets.Property)]
    [Description("整型长度验证失败")]
    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;
        }
    }


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


//字符串长度范围验证
    //限制该特性,只能用于属性
    [AttributeUsage(AttributeTargets.Property)]
    [Description("字符串长度范围超出规定")]
    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;
        }
    }
View Code

 

3、增加AttributeExtend类的Validate方法重载

//参数里面this关键字 特别重要,加了this,可以直接在实体类的扩展方法里找到Validate,否则看不到
        /// <summary>
        /// 扩展方法(用来验证实体类的各个参数是否符合预期)
        /// </summary>
        /// <typeparam name="T">目标类</typeparam>
        /// <param name="t">目标类的实例化对象</param>
        /// <param name="errMsg">带出错误验证后的提示信息</param>
        /// <returns>验证结果true或false</returns>
        public static bool Validate<T>(this T t,out string errMsg)
        {
            errMsg = "";
            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))
                        {
                            Type type1 = attribute.GetType();
                            foreach (var item in type1.GetCustomAttributes(true))
                            {
                                if (item.GetType().Equals(typeof(DescriptionAttribute)))
                                {
                                    errMsg = ((DescriptionAttribute)item)._Description;
                                }
                            };
                            return false;
                        }
                    }  

                }
            }
            return true;
        }

 

4、调用测试

//实战实体类验证
            Student student = new Student
            {
                Id = 1,
                StudentName = "张三张三张三",
                Email="22@qq.com",
                Phone="12345678900"
            };
            Console.WriteLine("--------只验证结果的Validate方法-------");
            bool result1 = student.Validate();
            Console.WriteLine(result1);

            Console.WriteLine("--------可以带出错误提示的Validate方法-------");
            string errMsg = String.Empty;
            bool result = student.Validate(out errMsg);
            Console.WriteLine(result);
            Console.WriteLine(errMsg);

 

5、结果

 

 

 

 

posted @ 2022-08-22 15:59  狼窝窝  阅读(89)  评论(0)    收藏  举报