学海无涯

导航

统计

数据校验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

posted on   宁静致远.  阅读(414)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
点击右上角即可分享
微信分享提示