不消说,法则验证很重要,无效的参数,大概会导致措施的异常。
假如利用Web API或MVC页面,那么大概习惯了自带的法则验证,我们的节制器很清洁:
public class User { [Required] public string FirstName { get; set; } [Required] public string LastName { get; set; } }
这种很常见,可是本日我想给你一个更好的替代方案:FluentValidation, 通过这个库,您可以流通地界说用于工具验证的巨大法则,从而轻松构建和领略验证法则,您可以在 Github 上找到这个项目。
安装 FluentValidation我新建了一个很简朴的.NET Core 的Web API 措施,只有一个接口是用户注册,入参是一个User类, 然后在Nuget中安装 FluentValidation。
建设第一个验证
对付要验证的每个类,必需建设其本身的验证器,每个验证器类都必需担任AbstractValidator<T>,个中T是要验证的类,而且所有验证法则都在结构函数中界说。
最简朴的验证是针对空值,假如要指定FirstName和LastName都不能为空,这个验证器是这样:
public class UserValidator : AbstractValidator<User> { public UserValidator() { RuleFor(x => x.FirstName).NotEmpty(); RuleFor(x => x.LastName).NotEmpty(); } }
就这些了,您已经建设了第一个验证器,是不是超等简朴!
尚有一些其他的法则,好比 MinimumLength,MaximumLength和Length,用于验证长度,您可以把多个法则指定到一个字段,就像这样:
public class UserValidator : AbstractValidator<User> { public UserValidator() { RuleFor(x => x.FirstName).NotEmpty(); RuleFor(x => x.FirstName).MinimumLength(3); RuleFor(x => x.FirstName).MaximumLength(20); RuleFor(x => x.LastName).NotEmpty(); } }
验证入参我们之前已经界说了验证法则,此刻开始利用它,您只需要new 一个UserValidator工具,然后挪用Validate要领, 它会返回一个工具,个中包括了验证状态和所有没有通过验证的信息。
[HttpPost] public IActionResult Register(User newUser) { var validator = new UserValidator(); var validationResult = validator.Validate(newUser); if (!validationResult.IsValid) { return BadRequest(validationResult.Errors.First().ErrorMessage); } return Ok(); }
假如我运行措施,然后输入一个超长的名字:
{ "FirstName": "赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张", "LastName": "张" }
我会收到验证错误:"The length of 'First Name' must be 20 characters or fewer. You entered 24 characters"。
好吧,我不喜欢这个动静,那么你可以自界说错误动静,这很简朴,您可以利用 WithMessage 要领。
- RuleFor(x => x.FirstName).MaximumLength(20); + RuleFor(x => x.FirstName).MaximumLength(20).WithMessage("您的名字长度已经超出了限制!");
流利验证你可以把验证法则,改成下边这样:
- RuleFor(x => x.FirstName).NotEmpty(); - RuleFor(x => x.FirstName).MinimumLength(3); + RuleFor(x => x.FirstName).NotEmpty().MinimumLength(3);
然后也可以把验证法则应用于其他的属性,就像这样:
public UserValidator() { RuleFor(x => x.FirstName) .MaximumLength(20).WithMessage("您的名字长度已经超出了限制!") .NotEmpty().MinimumLength(3); RuleFor(x => x.LastName).NotEmpty(); }
常见的验证法则这个库有许多现成的根基范例验证法则, 对付字符串,您可以利用差异的要领,好比 EmailAddress,IsEnumName(查抄值是否在指定的Enum范例中界说)和 InclusiveBetween, 查抄该值是否在界说的范畴内。
此刻,我在User类添加了别的两个字段,Password 和 ConfirmPassword。
Password字段是一个字符串,有效的长度必需在5到15个字符之间,而且要切合正则,为了界说是否满意安详法则,我界说了一个HasValidPassword要领,它会返回一个bool值。
private bool HasValidPassword(string pw) { var lowercase = new Regex("[a-z]+"); var uppercase = new Regex("[A-Z]+"); var digit = new Regex("(\\d)+"); var symbol = new Regex("(\\W)+"); return (lowercase.IsMatch(pw) && uppercase.IsMatch(pw) && digit.IsMatch(pw) && symbol.IsMatch(pw)); }
然后在暗码验证中利用:
RuleFor(x => x.FirstName) .MaximumLength(20).WithMessage("您的名字长度已经超出了限制!") .NotEmpty().MinimumLength(3); RuleFor(x => x.LastName).NotEmpty(); RuleFor(x => x.Password) .Length(5, 15) .Must(x => HasValidPassword(x));
还可以简化一些:
RuleFor(x => x.Password) .Length(5, 15) - .Must(x => HasValidPassword(x)); + .Must(HasValidPassword); }
ConfirmPassword字段的独一要求是便是Password字段:
RuleFor(x => x.ConfirmPassword) .Equal(x => x.Password) .WithMessage("2次暗码纷歧致!");
注入验证器修改Startup类中的ConfigureServices要领:
public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddFluentValidation(); services.AddTransient<IValidator<User>, UserValidator>(); }
留意:这个处所的生命周期是 Transient。
这样,在挪用注册接口的时候,会自动举举措则验证:
[HttpPost] public IActionResult Register(User newUser) { return Ok(); }
然后,我们再实验传入参数来挪用接口:
{ "FirstName": "赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张", "LastName": "张" }
很明明,验证不通过,接口会返回这样的错误信息: