ASP.NET Core数据校验FluentValidation

发布于:2025-02-10 ⋅ 阅读:(9) ⋅ 点赞:(0)

内置数据校验机制

  1. .NET Core中内置了对数据校验的支持,在System.ComponentModel.DataAnnotations这个命名空间下,比如[Required]、[EmailAddress] 、[RegularExpression]。CustomValidationAttribute、IValidatableObject。
  2. 内置的校验机制的问题:校验规则都是和模型类耦合在一起,违反“单一职责原则”;很多常用的校验都需要编写自定义校验规则,而且写起来麻烦。

FluentValidation

ASP.NET Core — FluentValidation 文档https://docs.fluentvalidation.net/en/latest/aspnet.html

用类似于EF Core中Fluent API的方式进行校验规则的配置,也就是我们可以把对模型类的校验放到单独的校验类中。

  1. NuGet:Install-Package FluentValidation
  2. 在Program.cs中注册服务
    //注册当前程序集所有Validator
    builder.Services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
    //注册指定程序集所有Validator
    //builder.Services.AddValidatorsFromAssembly(Assembly.Load(""));
  3. 创建NewPerson类
    public record NewPerson
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Password { get; set; }
        public int Age { get; set; }
        public string Email  { get; set; }
    }
  4. 创建一组验证规则NewPersonValidator类,继承自AbstractValidator<NewPerson>
    public class NewPersonValidator : AbstractValidator<NewPerson>
    {
        public NewPersonValidator()
        {
            RuleFor(x => x.Name).NotEmpty().MaximumLength(50).WithMessage("姓名不能为空")
                .MustAsync(async (x, _) => await Task.FromResult(1 == 1))
                .WithMessage(x=>$"用户名{x.Name}已存在");
            RuleFor(x => x.Age).InclusiveBetween(1, 200).WithMessage("年龄必须在1-200之间");
            RuleFor(x => x.Password).NotNull().WithMessage("密码不能为空").Length(6, 10).WithMessage("密码为6-9位");
            RuleFor(x => x.Email).NotNull().EmailAddress().WithMessage("邮箱格式不正确")
                .Must(o => o.EndsWith("@qq.com") || o.EndsWith("@163.com"))
                .WithMessage("只支持163和QQ邮箱");
        }
    }
  5. 手动验证
     
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class DemoController : ControllerBase
    {
        private readonly IValidator<NewPerson> Validator_Person;
    
        public DemoController(IValidator<NewPerson> validator_Person)
        {
            Validator_Person = validator_Person;
        }
    
        [HttpGet]
        public async Task<IActionResult> Person(NewPerson p)
        {
            //手动验证
            var validationResult = await Validator_Person.ValidateAsync(p);
            return Ok(validationResult);
        }
    }