学海无涯

导航

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

posted on 2022-10-07 10:01  宁静致远.  阅读(387)  评论(0编辑  收藏  举报