不用说,规则验证很重要,无效的参数,可能会导致程序的异常。
如果使用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": "张" }
很明显,验证不通过,接口会返回这样的错误信息:
{ "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1", "title": "One or more validation errors occurred.", "status": 400, "traceId": "|c4523c02-4899b7f3df86a629.", "errors": { "FirstName": [ "您的名字长度已经超出了限制!" ] } }
希望对您有帮助,您可以在官方文档中找到更多的用法。
原文链接: https://www.code4it.dev/blog/fluentvalidation
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 徐玮1980-我爱校园[台湾复刻版][WAV+CUE]
- 刘亦菲分享靶场射击视频 网友夸赞又美又飒
- 《怪物猎人:荒野》试玩现已开放 你最想尝试哪种武器?
- 《异度之刃X 终极版》正式公布!明年3月20日登陆NS
- 【原神】V5.1攻略 | 纳西妲角色培养攻略
- 【原神】V5.1攻略 | 纳西妲与胡桃抽取建议
- 【原神】V5.1攻略 | 纳西妲一图流攻略
- 群星.2003-重遇80·感动今天的都市人2CD【SONY】【WAV+CUE】
- 希文.2024-沉溺【StreetVoice】【FLAC分轨】
- 韩红.2005-精丫麒麟童】【WAV+CUE】
- 2D像素风日式美学动作游戏《雨魂》将登陆Xbox Series
- 《龙腾世纪4》评分造假?仅将评测代码给好评媒体!
- 《怪猎荒野》推出蜘蛛恐惧症设定 蜘蛛秒变史莱姆
- 《张韶涵单8CD+无损单曲合集》[WAV/FLAC][6.5G]
- 自然声带《大自然 雨声 白噪音》[320K/MP3][135.32MB]