微信公众号:趣编程ACE
收集并分享日常.NET实战开发技巧,源码获取关注后回复 源码;
**如果你觉得对你有帮助,欢迎关注
.NET6中使用FluentValidation验证组件
**本文来自社区群粉丝投稿**
我们在日常开发中后端也需要对前端传递的参数或者json实体进行验证,这样保证代码的健壮性。常规做法是利用正则或者DataAnnoations里面的特性实现。
本文将会介绍一个开箱即用的验证组件FluentValidation来高效验证我们需要的对象。
官网地址
https://fluentvalidation.net/
Nuget 安装
dotnet add package FluentValidation.AspNetCore

实体验证
比如下面这个接口需要一个User类型的对象作为形参,我们对这个形参进行验证:

1public class User
2{
3 public string? UserName { get; set; }
4 public int Age { get; set; }
5 public string? Email{get;set;}
6 public string? Address { get; set; }
7 public string? PhoneNumber { get; set; }
8 public Roles[]? Roles {get;set;} // Roles 类型的数组
9}
10// 利用新特性 record RoleNames为Roles类的属性
11public record Roles(string RoleNames);
这里有一个需要验证的User类,我们需要对这个类型字段进行非空、null值、范围长度等等验证,上文已经安装好验证组件包,那么我们就可以开始验证:
1public UserValidator()
2{
3 RuleFor(u=>u.UserName).NotEmpty().NotNull(); // 不为空 不为null
4 RuleFor(u=>u.Email).EmailAddress(); // 需要是一个邮箱格式
5 RuleFor(u=>u.Address).NotEmpty().MaximumLength(10); // 地址不为空 且最大长度为10
6 RuleFor(u=>u.Address)
7 .Must(r=>r?.ToLower().Contains("suzhou")==true).WithMessage("Address must contain suzhou"); // 地址必须包含 suzhou
8 // 法一
9 // RuleForEach(f=>f.Roles)
10 // .ChildRules(c=>c.RuleFor(r=>r.RoleNames).NotEmpty()); // 对集合的对象进行验证
11
12 // 法二
13 RuleForEach(f=>f.Roles).SetValidator(new UserRoleValidator());
14}
新建一个UserValidator类 继承自AbstractValidator,其中AbstractValidator
在类的构造函数中可以发现,我们利用
RuleFor()对简单字段进行验证,但对于复杂类型的字段,比如 Roles字段,它是一个对象数组,那么我们需要对对象数组验证则可以使用
RuleForEach()方法,具体可以参考官网代码示例。
有了这个验证类,我们就需要在
Program.cs里面配置一下验证类型,操作如下:
1builder.Services.AddControllers()
2 .AddFluentValidation(c =>
3 {
4 // 从程序集中注册 获取所需要的验证类型
5 c.RegisterValidatorsFromAssembly(Assembly.GetExecutingAssembly());
6 });
然后在Swagger里面调用接口,将邮箱格式给错,地址中不包含 suzhou 得到如下效果:

参数验证
以上便是对实体类对象简单验证,但是如果我们API接口接受的查询参数,不是实体类 如下所示:

那么我们怎么对形参进行验证呢?通过查看官网文档 我发现可以将参数转化为实体类 然后调用验证对应的验证方法
发现Validators 可以被依赖注入 注入成 IValidator
新建一个IUserManage 接口 后续将这个接口注入到API层
1public interface IUserManager
2{
3 Task ValidateUser(User user); // 核心逻辑 调用这个方法就可以实现对对象的验证
4}
新建 UserManage 实现IUserManage
1public class UserManage:IUserManager
2{
3 private readonly IValidator<User> _validator;
4
5 public UserManage(IValidator<User> _validator)
6 {
7 this._validator = _validator;
8 }
9
10 public async Task ValidateUser(User user)
11 {
12 var validationResult = await _validator.ValidateAndThrowAsync(user);
13 }
14}
在Pragram.cs 里面注入我们IUserManage 和 UserManage 还有自动注册程序集所有继承了AbstractValidator
1builder.Services.AddValidatorsFromAssemblyContaining<UserValidator>();
2builder.Services.AddScoped<IUserManager,UserManage>();
最后在API 层调用
1 [HttpGet]
2 public async Task<IActionResult> GetUser(string userName,string email)
3 {
4 // 将参数转化为对象 进行验证 _userManager 依赖注入得到
5 _userManager.ValidateUser(new User{UserName=userName,Email=email});
6 return Ok();
7 }


PS:为了直观感受,录制了一部分视频(待更),如需源码后台留言即可!

