一. 简介html
写完上一个章节MVC中的经常使用特性,火烧眉毛将该系列补全,该章节主要介绍数据批注(也叫:注解)。前端
一听【数据批注】,好高大上的名字,但仔细一看,它们实际上是【System.ComponentModel.DataAnnotations】程序集下的一些特性类,O(∩_∩)O哈哈~,既然是特性,就符合特性的全部特征,只不过这些特性是做用于“属性”上的。ajax
再一看【System.ComponentModel.DataAnnotations】这个命名空间,有点眼熟,与以前EF中的一篇文章【EF的CodeFirst模式经过DataAnnotations修改默认协定】中的一类操做来源于同一个命名空间下。数据库
因此综上所述:该命名空间下的特性,在EF中能够用来映射生成数据库中的表字段,在平常开发中也能够用于作类中属性的限制和验证。安全
原理:均继承了ValidationAttribute特性,经过覆写IsValide方法进行校验。服务器
适用场景:不少项目须要客户端和服务器端进行双重格式验证,使之更加安全,这时服务器端就可使用数据批注了来进行校验了。并发
以Required特性为例,查看一下源码:框架
二. 经常使用的数据批注ide
这里总结一下【System.ComponentModel.DataAnnotations】命名空间下经常使用的数据批注,即特性。测试
① Key :声明主键
② Required:非空声明
③ MinLength和MaxLength:设置string类型的最大长度和最小长度,数据库的对应nvarchar
④ StringLength:设置string类型的长度,数据库对应nvarchar
⑤ Compare:新老密码对比
⑥ RegularExpression:正则的匹配
⑦ Phone:验证手机号码
⑧ Range:验证范围
⑨ Timestamp:将byte[]类型设置为timestamp类型
⑩ ConcurrencyCheck:并发检查,执行update操做时,会检查并发性(乐观锁) (在后面并发章节着重介绍Timestamp和ConcurrencyCheck)
另外还有一些不是很经常使用的,如:
① DisplayName:声明属性的名称
② Remote:远程验证,须要JQuery插件的支持 (这里不作测试等待补充 参考: https://www.cnblogs.com/JustRun1983/p/3505151.html)
下面补充一下该命名空间反射源码,能够自行查找须要的批注:
代码测试:
(1). 实体类,在其属性上添加数据标注
1 /// <summary> 2 /// 用户信息类 ,用于测试框架自己提供的数据批注 3 /// </summary> 4 public class UserInfor 5 { 6 [Required] 7 public string id { get; set; } 8 9 [StringLength(4)] 10 public string userName { get; set; } 11 12 [MaxLength(8)] 13 public string userMsg { get; set; } 14 15 [Range(2, 10)] 16 public int userAge { get; set; } 17 18 [RegularExpression("[a-d]")] //a-d中的一个 19 public string userMsg3 { get; set; } 20 21 [Phone] 22 public string userPhone { get; set; } 23 24 public string userOldPwd { get; set; } 25 26 [Compare("userOldPwd")] //比较和userOldPwd的值是否相等 27 public string userNewPwd { get; set; } 28 29 }
(2). 前端代码
1 //1. 测试数据批注 2 $("#btn1").click(function () { 3 $.ajax({ 4 type: "Post", 5 url: "TestDataAnnotationModel", 6 data: { 7 "id":"123", 8 "userName": "mr12", 9 "userMsg": "ypf1234", 10 "userAge": 6, 11 "userMsg3": "a", 12 "userPhone": "15764222366", 13 "userOldPwd": "123456", 14 "userNewPwd":"123456" 15 16 }, 17 success: function (data) { 18 if (data == "ok") { 19 alert("测试经过"); 20 } 21 if (data == "error") { 22 alert("测试未经过"); 23 } 24 } 25 }); 26 });
(3). 服务器端代码
1 public ActionResult TestDataAnnotationModel(UserInfor user) 2 { 3 //经过该方法进行验证 4 var isValidate = ModelState.IsValid; 5 6 if (isValidate) 7 { 8 return Content("ok"); 9 } 10 return Content("error"); 11 }
三. 自定义数据批注
思路:经过上面的批注源码可知,均为自定义类继承:ValidationAttribute,覆写IsValid方法
需求:这里咱们自定义一个批注,要求不为空,且长度区间为6-12位
使用方法一样为:action中经过实体接收,经过ModelState.IsValid的值为true或false来判断验证是否经过
代码测试:
(1). 实体类和自定义批注
1 /// <summary> 2 /// 角色类,用于测试自定义业务的数据批注 3 /// </summary> 4 public class RoleInfor 5 { 6 7 public string id { get; set; } 8 9 [myOwnCheck] 10 public string roleName { get; set; } 11 } 12 13 /// <summary> 14 /// 自定义数据批注,要求非空且长度为6-12位 15 /// </summary> 16 public class myOwnCheckAttribute : ValidationAttribute 17 { 18 public override bool IsValid(object value) 19 { 20 if (value != null && value.ToString().Length > 6 && value.ToString().Length < 12) 21 { 22 return true; 23 } 24 return false; 25 } 26 }
(2). 前端代码
1 //2. 测试自定义业务逻辑的验证 2 $("#btn2").click(function () { 3 $.ajax({ 4 type: "Post", 5 url: "TestMyOwnCheck", 6 data: { 7 "id": "123", 8 "roleName": "mr12345" 9 }, 10 success: function (data) { 11 if (data == "ok") { 12 alert("测试经过"); 13 } 14 if (data == "error") { 15 alert("测试未经过"); 16 } 17 } 18 }); 19 });
(3). 服务器端代码
1 public ActionResult TestDataAnnotationModel(UserInfor user) 2 { 3 //经过该方法进行验证 4 var isValidate = ModelState.IsValid; 5 6 if (isValidate) 7 { 8 return Content("ok"); 9 } 10 return Content("error"); 11 }
四. Model级别的验证扩展
实现IValidaableObjec接口,实现Validate方法。(了解便可)
1 public class CarInfor: IValidatableObject 2 { 3 public string id { get; set; } 4 5 public string carName { get; set; } 6 7 public int carAge { get; set; } 8 9 IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext) 10 { 11 if (carAge % 2 == 0) 12 { 13 var result = new ValidationResult("车龄验证不经过", new string[] { "carAge" }); 14 15 yield return result; 16 } 17 } 18 }