【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; 原因是:学生姓名超过定义的长度范围了