数据校验FluentValidation.AspNetCore
FluentValidation 可在 ASP.NET Core Web 应用程序中用于验证传入模型。有两种主要方法可以做到这一点:
- 手动验证
- 自动验证
通过手动验证,您将验证器注入您的控制器(或 api 端点),调用验证器并对结果采取行动。这是最直接和最可靠的方法。
通过自动验证,FluentValidation 插入作为 ASP.NET Core MVC 一部分的验证管道,并允许在调用控制器操作之前验证模型(在模型绑定期间)。这种验证方法更加无缝,但有几个缺点:
- 自动验证不是异步的:如果您的验证器包含异步规则,那么您的验证器将无法运行。如果您尝试使用带有自动验证的异步验证器,您将在运行时收到异常。
- 自动验证仅适用于 MVC:自动验证仅适用于 MVC 控制器和 Razor 页面。它不适用于更现代的 ASP.NET 部分,例如 Minimal API 或 Blazor。
- 自动验证很难调试:自动验证的“神奇”特性使得如果出现问题很难调试/排除故障,因为在幕后做了很多事情。
我们通常不建议对新项目使用自动验证,但它仍可用于旧版实现。
一、用NuGet安装 FluentValidation.AspNetCore 包
二、验证模型
1 | public record Login2Request( string Email, string Password, string Password2); |
1 2 3 4 5 6 7 8 9 10 11 12 | public class Login2RequestValidator : AbstractValidator<Login2Request> { //Login2Request的数据校验类 public Login2RequestValidator() { RuleFor(x => x.Email).NotNull().EmailAddress() .Must(v => v.EndsWith( "@qq.com" ) || v.EndsWith( "@163.com" )) .WithMessage( "只支持QQ和163邮箱" ); RuleFor(x => x.Password).NotNull().Length(3, 10) .WithMessage( "密码长度必须介于3到10之间" ) .Equal(x => x.Password2).WithMessage( "两次密码必须一致" ); } } |
2.1 手动验证(推荐)
注册验证器
1 2 | //注册验证器 services.AddScoped<IValidator<Login2Request>, Login2RequestValidator>(); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | [Route( "api/[controller]" )] [ApiController] public class FluentValidatorsController : ControllerBase { private readonly IValidator<Login2Request> _validator; public FluentValidatorsController(IValidator<Login2Request> validator) { _validator = validator; } [Route(nameof(Create))] [HttpPost] public async Task<ActionResult> Create(Login2Request model) { FluentValidation.Results.ValidationResult result = await _validator.ValidateAsync(model); if (!result.IsValid) { result.AddToModelState( this .ModelState); return ValidationProblem(ModelState); } return Ok(model); } } |
验证错误信息
MVC控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | public class PeopleController : Controller { private IValidator<Person> _validator; private IPersonRepository _repository; public PeopleController(IValidator<Person> validator, IPersonRepository repository) { // Inject our validator and also a DB context for storing our person object. _validator = validator; _repository = personRepository; } public ActionResult Create() { return View(); } [HttpPost] public async Task<IActionResult> Create(Person person) { ValidationResult result = await _validator.ValidateAsync(person); if (!result.IsValid) { // Copy the validation results into ModelState. // ASP.NET uses the ModelState collection to populate // error messages in the View. result.AddToModelState( this .ModelState); // re-render the view when validation failed. return View( "Create" , person); } _repository.Save(person); //Save the person to the database, or some other logic TempData[ "notice" ] = "Person successfully created" ; return RedirectToAction( "Index" ); } } |
验证中执行异步操作,仅手动验证支持
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class Login2RequestValidator : AbstractValidator<Login2Request> { //Login2Request的数据校验类 private readonly IdDbContext _dbContext; public Login2RequestValidator(IdDbContext dbContext) { RuleFor(x => x.Email).NotNull().EmailAddress() .Must(v => v.EndsWith( "@qq.com" ) || v.EndsWith( "@163.com" )) .WithMessage( "只支持QQ和163邮箱" ); RuleFor(x => x.Password).NotNull().Length(3, 10) .WithMessage( "密码长度必须介于3到10之间" ) .Equal(x => x.Password2).WithMessage( "两次密码必须一致" ); _dbContext = dbContext; RuleFor(x => x.UserName).NotNull()<br> .MustAsync(async (m, cancellation) => await _dbContext.Users.AnyAsync(u => u.UserName == m))<br><br> .WithMessage(c => $ "用户名{c.UserName}不存在" );<em id= "__mceDel" > } } </em> |
2.2 自动验证
1 2 3 4 5 6 7 | //Fluent数据校验 //注册验证器 services.AddScoped<IValidator<Login2Request>, Login2RequestValidator>(); //或者通过程序集注册验证器 //services.AddValidatorsFromAssemblyContaining<Login2RequestValidator>(); services.AddFluentValidationAutoValidation(); //注册自动验证 //services.AddFluentValidationClientsideAdapters(); |
执行 Create 请求之前,会先执行以上设置的验证,验证通过才执行Create方法体
1 2 3 4 5 6 7 8 9 10 11 | [Route( "api/[controller]" )] [ApiController] public class FluentValidatorsController : ControllerBase { [Route(nameof(Create))] [HttpPost] public async Task<ActionResult> Create(Login2Request model) { return Ok(model); } } |
验证失败
参考:https://docs.fluentvalidation.net/en/latest/aspnet.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章