.NET 数据合理性校验浅谈
仅仅个人的一点小总结,把数据校验分为横向校验与纵向校验;
横向:对各个属性的单独或多个一起比较,如用户注册的信息,邮箱是否符合格式等,2次输入的密码是否一致,密码的复杂度等,这类验证方法很多,可以自己给属性加特性标志,然后统一方法验证,自己定规则啦,还有很多其他框架可以使用;
纵向:如用户注册的邮箱地址、手机号码,现有用户是否已经使用了,简单说就是和同类比,当然还有其他的;
来个例子:
还是2个实体
1 public class Room 2 { 3 public int Id { get; set; } 4 public string Number { get; set; } 5 public string Building { get; set; } 6 public string Address 7 { 8 get 9 { 10 if (Number != null && Building != null) 11 { 12 return Building + Number; 13 } 14 return ""; 15 } 16 } 17 public int Max { get; set; } 18 }
1 public class Student 2 { 3 public int Id { get; set; } 4 public string Name 5 { 6 get; 7 set; 8 } 9 public DateTime Brithday 10 { 11 get; 12 set; 13 } 14 15 public double High 16 { 17 get; 18 set; 19 } 20 21 public decimal Money 22 { 23 get; 24 set; 25 } 26 27 public bool Enable 28 { 29 get; 30 set; 31 } 32 33 public int? RoomId 34 { 35 get; 36 set; 37 } 38 public Room Room 39 { 40 get; 41 set; 42 } 43 public double Qty 44 { 45 get; 46 set; 47 } 48 public string TelNumber { get; set; } 49 public decimal Price 50 { 51 get; 52 set; 53 } 54 55 }
简单模拟一些数据:
1 /// <summary> 2 /// 模拟数据源 3 /// </summary> 4 public static class Database 5 { 6 public static List<Room> Rooms { get; set; } 7 8 9 public static List<Student> Students { get; set; } 10 static Database() 11 { 12 #region 添加模拟数据 13 if (Rooms == null) 14 { 15 Rooms = new List<Room>{new Room { Id=1, Number="101", Building="A栋", Max=8 }}; 16 } 17 #endregion 18 if(Students==null) 19 { 20 Students = new List<Student>(); 21 Room r1 = Rooms.FirstOrDefault(); 22 for (int i = 0; i < 5; i++) 23 { 24 Student stu = new Student { Id = i + 1, RoomId = r1.Id, Room = r1, Brithday = DateTime.Now.AddYears(-20), High = 170.5 + i, Money = 200000.5m + i, Name = "Jack" + i }; 25 if (i == 2) 26 stu.TelNumber = "18866668888"; 27 Students.Add(stu); 28 } 29 } 30 } 31 }
使用FluentValidation,添加AbstractValidator子类,在构造方法中添加对Student实体校验的规则,属于横向校验
1 public class StudentValidator: AbstractValidator<Student> 2 { 3 public StudentValidator() 4 { 5 RuleFor(stu => stu.Brithday).LessThanOrEqualTo(DateTime.Now.AddYears(-18)).WithMessage("年龄不能小于18周岁"); 6 RuleFor(stu => stu.High).LessThanOrEqualTo(250).WithMessage("身高不能大于250cm"); 7 RuleFor(stu => stu.Money).InclusiveBetween(100000, 100000000).WithMessage("10万到1亿之间的资产才能读书"); 8 RuleFor(stu => stu.Price).GreaterThan(0).WithMessage("价格必须大于0"); 9 } 10 }
控制台验证看看:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 #region 横向校验,可以放到客户端校验,基本上服务器在api接收到数据也要校验 6 ////提交上来的数据,身高3000cm,2年前出生 7 //Student stu = new Student { High = 3000, Brithday = DateTime.Now.AddYears(-2),Money=100000,Price=-1 }; 8 //StudentValidator validator = new StudentValidator(); 9 //var result=validator.Validate(stu); 10 //if (!result.IsValid) 11 //{ 12 // var msgList= result.Errors.Select(a => a.ErrorMessage); 13 // Console.WriteLine("实体验证失败:\r\n"+string.Join(";",msgList)); 14 // return; 15 //} 16 #endregion 17 18 #region 纵向校验,假设已经通过横向校验;一般放到业务层 19 //业务场景:添加Student给他分配Room,检查该Room是否还有位置 20 Room r1 = Database.Rooms.FirstOrDefault(); 21 22 Student stu = new Student { TelNumber = "18866668888", Name = "Bob", High = 180, Brithday = DateTime.Now.AddYears(-20), RoomId = r1.Id, Room = r1 }; 23 bool pass = false; 24 string validResult = Valid(stu, out pass); 25 Console.WriteLine(validResult); 26 if (pass) 27 { 28 //通过校验,继续 29 Console.WriteLine("写入数据库..."); 30 Database.Students.Add(stu); 31 32 Console.WriteLine($"我住到{r1.Number}啦,我们一共{Database.Students.Where(a => a.RoomId == r1.Id).Count()}人"); 33 } 34 35 #endregion 36 } 37 public static string Valid(Student stu, out bool pass) 38 { 39 40 if (Database.Students.Exists(a => a.TelNumber == stu.TelNumber)) 41 { 42 pass = false; 43 return "你这个电话号码有人用了"; 44 } 45 Room r1 = Database.Rooms.FirstOrDefault(a => a.Id == stu.RoomId); 46 if (r1 == null) 47 { 48 pass = false; 49 return "不存在该宿舍啊"; 50 } 51 52 53 int max = r1.Max; 54 int currentNum = Database.Students.Where(a => a.RoomId == r1.Id).Count(); 55 if (max > currentNum) 56 { 57 pass = true; 58 return $"最多住{max}人,现在住{currentNum}人,还有位置"; 59 } 60 else 61 { 62 pass = false; 63 return "人满了"; 64 } 65 66 } 67 }
Over
另外,在.NET MVC开发方式,给实体添加验证的特性,生成的视图模板同样可以在浏览器端进行验证,主要通过jquery.validate.js与jquery.validate.unobtrusive.js进行校验,都属于横向的校验。

浙公网安备 33010602011771号