C# 利用特性(Attribute)实现通用实体类数据合法校验
时间:2019-08-21
本文章向大家介绍C# 利用特性(Attribute)实现通用实体类数据合法校验,主要包括C# 利用特性(Attribute)实现通用实体类数据合法校验使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
用过asp.net mvc 的都应该知道,在实体类上添加一些特性,可以实现后端实体的数据校验,这里简单实现一下
实现原理:利用反射获取实体的每一个属性,并通过属性获取属性上标注的特性,调用特性的Validate方法(此方法自定义的)来验证属性的值是否合法。
1、创建自己的校验特性基类
此类继承了Attribute,表明为一个特性,Validate方法为抽象方法,目的是给实现的子类自己定义自己的Validate方法。error为错误消息提示信息。
1 [AttributeUsage(AttributeTargets.Property,AllowMultiple = true)] 2 public abstract class BaseAttribute:Attribute 3 { 4 public virtual string error { get; set; } 5 public abstract bool Validate(object value); 6 }
2、创建特性类继承自BaseAttribute
这里只简单写3个特性,写法都一样,只是校验方法Validate中的逻辑不一样。
1 /// <summary> 2 /// 约束属性不能为空 3 /// </summary> 4 public class RequiredAttribute : BaseAttribute 5 { 6 public override string error { 7 get 8 { 9 if (base.error != null) 10 { 11 return base.error; 12 } 13 return "属性不能为空"; 14 } 15 set => base.error = value; 16 } 17 public override bool Validate(object value) 18 { 19 return !(value == null); 20 } 21 }
1 /// <summary> 2 /// 约束字符串的长度范围 3 /// </summary> 4 public class StringRangeAttribute : BaseAttribute 5 { 6 public int min { get; set; } 7 public int max { get; set; } 8 public override string error { 9 get { 10 if (base.error != null) 11 { 12 return base.error; 13 } 14 return $"字符串长度范围{this.min}-{this.max}"; 15 } 16 set => base.error = value; } 17 public override bool Validate(object value) 18 { 19 return value.ToString().Length >= this.min && value.ToString().Length <= this.max; 20 } 21 }
1 /// <summary> 2 /// 约束符合正则表达式 3 /// </summary> 4 public class RegexAttribute : BaseAttribute 5 { 6 public string regexText; 7 public override bool Validate(object value) 8 { 9 var regex = new Regex(regexText); 10 return regex.Match(value.ToString()).Success; 11 } 12 }
3、给实体类扩展一个方法,用来验证实体类实例属性值是否合法
此方式的扩展方法会污染其他非实体类,不是太推荐用太多此种扩展写法,其实这里不写成扩展方法也没什么问题。
此扩展方法会验证实例中的所有属性,并将所有不通过验证的属性的提示信息以字符串的形式返回,所有都验证通过则返回空串。
1 public static string Validate<T>(this T t) 2 { 3 Type type = t.GetType(); 4 5 //获取所有属性 6 PropertyInfo[] propertyInfos = type.GetProperties(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic); 7 List<string> errorList = new List<string>(); 8 foreach (PropertyInfo propertyInfo in propertyInfos) 9 { 10 if(propertyInfo.IsDefined(typeof(BaseAttribute)))//如果属性上有定义该属性,此步没有构造出实例 11 { 12 foreach (BaseAttribute attribute in propertyInfo.GetCustomAttributes(typeof(BaseAttribute))) 13 { 14 if (!attribute.Validate(propertyInfo.GetValue(t, null))) 15 { 16 errorList.Add( $"[{propertyInfo.Name}]" + attribute.error); 17 } 18 } 19 20 } 21 } 22 return string.Join(",", errorList); 23 }
4、定义一个实体类,并测试(控制台程序)。
假设有Student.cs ,在其id属性中添加Required特性,name属性上添加StringRange和Regex特性。
1 public class Student 2 { 3 [Required(error = "id 不能为空!")] 4 public int? id { get; set; } 5 [Regex(regexText = "^a.*a$",error = "属性不合格规则")] 6 [StringRange(min =5,max =10)] 7 public string name { get; set; } 8 }
1 static void Main(string[] args) 2 { 3 Student student = new Student() 4 { 5 id = null, 6 name = "ajiudsagasgasgaxb" 7 }; 8 string errorStr = student.Validate(); 9 Console.WriteLine(errorStr); 10 Console.ReadKey(); 11 }
测试结果
此代码纯属自己理解的原理性还原,代码可能有多处写的不严谨。
原文地址:https://www.cnblogs.com/fnz0/p/11387835.html
- 移除 WordPress 后台插件管理的“编辑”与“停用”功能
- 区域设置 ID (LCID) 表
- jquery 表单事件
- Jexus以.NET(Phalanger)方式支持PHP的网站
- jquery鼠标事件
- Jexus 负载均衡
- 用.NET Framework 2.0创建 Form设计器[翻译]
- jquery事件绑定
- Fontello:免费Web-font 图标大集合(font-face 图标集)
- 通过 wp-config.php 禁止安装、升级或编辑WordPress 主题与插件
- 利用VS2005中的Code Snippets提高开发效率
- 用schemaSpy制作数据库文档
- WordPress 投票插件Post Ratings,可在谷歌搜索显示星级投票(附中文包下载)
- Spark学习笔记——共享变量
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 使用IDEA整合spring4+spring mvc+hibernate
- springmvc中@PathVariable和@RequestParam的区别
- centos7 安装mysql5.6
- bashdb安装及调试shell脚本
- linux awk指令详解
- linux sed指令详解
- Grafana使用zabbix自定义模板
- linux shell之变量的使用规则
- 第11期:压缩表
- grafana-zabbix插件安装和配置zabbix mysql
- grafana使用教程之API key
- Grafana使用教程之安装
- Java基础数据类型之包装类equals和==详解
- SCP不用密码传输文件
- Java 使用Collections.reverse对list集合进行降序排序