上一章我们在控制台中基本的了解了FluentValidation是如何简洁,优雅的完成了对实体的验证工作,今天我们将在实战项目中去应用它。
首先我们创建一个ASP.NET MVC项目,本人环境是VS2017,
创建成功后通过在Nuget中使用 Install-Package FluentValidation -Version 7.6.104 安装FluentValidation
在Model文件夹中添加两个实体Address 和 Person
public class Address { public string Home { get; set; } public string Phone { get; set; } }
public class Person { /// <summary> /// 姓名 /// </summary> public string Name { get; set; } /// <summary> /// 年龄 /// </summary> public int Age { get; set; } /// <summary> /// 性别 /// </summary> public bool Sex { get; set; } /// <summary> /// 地址 /// </summary> public Address Address { get; set; } }
紧接着创建实体的验证器
public class AddressValidator : AbstractValidator<Address> { public AddressValidator() { this.RuleFor(m => m.Home) .NotEmpty() .WithMessage("家庭住址不能为空"); this.RuleFor(m => m.Phone) .NotEmpty() .WithMessage("手机号码不能为空"); } }
public class PersonValidator : AbstractValidator<Person> { public PersonValidator() { this.RuleFor(p => p.Name) .NotEmpty() .WithMessage("姓名不能为空"); this.RuleFor(p => p.Age) .NotEmpty() .WithMessage("年龄不能为空"); this.RuleFor(p => p.Address) .SetValidator(new AddressValidator()); } }
为了更好的管理验证器,我建议将使用一个Manager者来管理所有验证器的实例。如ValidatorHub
public class ValidatorHub { public AddressValidator AddressValidator { get; set; } = new AddressValidator(); public PersonValidator PersonValidator { get; set; } = new PersonValidator(); }
现在我们需要创建一个页面,在默认的HomeController 控制器下添加2个Action:ValidatorTest,他们一个用于展示页面,另一个则用于提交。
[HttpGet] public ActionResult ValidatorTest() { return View(); } [HttpPost] public ActionResult ValidatorTest(Person model) { return View(); }
为 ValidatorTest 添加视图,选择Create模板,实体为Person
将默认的@Html全部删掉,因为在我们本次介绍中不需要,我们的目标是搭建一个前后端分离的项目,而不要过多的依赖于MVC。
最终我们将表单改写成了
@using (Html.BeginForm()) { @Html.AntiForgeryToken() <div> <h4>Person</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div> <label for="Name">姓名</label> <div> <input type="text" /> </div> </div> <div> <label for="Age">年龄</label> <div> <input type="text" /> </div> </div> <div> <label for="Home">住址</label> <div> <input type="text" /> </div> </div> <div> <label for="Phone">电话</label> <div> <input type="text" /> </div> </div> <div> <label for="Sex">性别</label> <div> <div> <input type="checkbox" /> </div> </div> </div> <div> <div> <input type="submit" value="Create" /> </div> </div> </div> }
注意,由于我们的实体Person中存在复杂类型Address,我们都知道,表单提交默认是Key:Value形式,而在传统表单的key:value中,我们无法实现让key为Address的情况下Value为一个复杂对象,因为input一次只能承载一个值,且必须是字符串。实际上MVC中存在模型绑定,此处不作过多介绍(因为我也忘记了-_-||)。
简单的说就是他能根据你所需要类型帮我们自动尽可能的转换,我们目前只要知道如何正确使用,在Address中存在Home属性和Phone属性,我们可以将表单的name设置为Address.Home,MVC的模型绑定会将Address.Home解析到对象Address上的Home属性去。
简单的校验方式我也不过多介绍了。再上一章我们已经了解到通过创建一个实体的验证器来对实体进行验证,然后通过IsValid属性判断是否验证成功。对,没错,对于大家来说这太简单了。但我们每次校验都创建一个验证器是否显得有点麻烦呢?不要忘了我们刚刚创建了一个ValidatorHub,我们知道控制器默认继承自Controller,如果我们想为控制器扩展一些能力呢?现在我要创建一个ControllerEx了,并继承自Controller。