【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; } }
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、结果


浙公网安备 33010602011771号