数据校验FluentValidation.AspNetCore
FluentValidation 可在 ASP.NET Core Web 应用程序中用于验证传入模型。有两种主要方法可以做到这一点:
- 手动验证
- 自动验证
通过手动验证,您将验证器注入您的控制器(或 api 端点),调用验证器并对结果采取行动。这是最直接和最可靠的方法。
通过自动验证,FluentValidation 插入作为 ASP.NET Core MVC 一部分的验证管道,并允许在调用控制器操作之前验证模型(在模型绑定期间)。这种验证方法更加无缝,但有几个缺点:
- 自动验证不是异步的:如果您的验证器包含异步规则,那么您的验证器将无法运行。如果您尝试使用带有自动验证的异步验证器,您将在运行时收到异常。
- 自动验证仅适用于 MVC:自动验证仅适用于 MVC 控制器和 Razor 页面。它不适用于更现代的 ASP.NET 部分,例如 Minimal API 或 Blazor。
- 自动验证很难调试:自动验证的“神奇”特性使得如果出现问题很难调试/排除故障,因为在幕后做了很多事情。
我们通常不建议对新项目使用自动验证,但它仍可用于旧版实现。
一、用NuGet安装 FluentValidation.AspNetCore 包
二、验证模型
public record Login2Request(string Email, string Password, string Password2);
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 手动验证(推荐)
注册验证器
//注册验证器 services.AddScoped<IValidator<Login2Request>, Login2RequestValidator>();
[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控制器
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");
}
}
验证中执行异步操作,仅手动验证支持
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()
.MustAsync(async (m, cancellation) => await _dbContext.Users.AnyAsync(u => u.UserName == m))
.WithMessage(c => $"用户名{c.UserName}不存在");
}
}
2.2 自动验证
//Fluent数据校验 //注册验证器 services.AddScoped<IValidator<Login2Request>, Login2RequestValidator>(); //或者通过程序集注册验证器 //services.AddValidatorsFromAssemblyContaining<Login2RequestValidator>(); services.AddFluentValidationAutoValidation();//注册自动验证 //services.AddFluentValidationClientsideAdapters();
执行 Create 请求之前,会先执行以上设置的验证,验证通过才执行Create方法体
[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
浙公网安备 33010602011771号