hale
发布于 2023-08-02 / 50 阅读 / 0 评论 / 0 点赞

第三方数据校验-FluentValidation

官网: FluentValidation — FluentValidation documentation

基本使用

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

  2. FluentValidation在ASP.NET Core项目中的用法

  • NuGet:FluentValidation.AspNetCore

  • 注入服务

// 弃用的方式
builder.Services.AddFluentValidation(fv => {
Assembly assembly = Assembly.GetExecutingAssembly();
fv.RegisterValidatorsFromAssembly(assembly);// RegisterValidatorsFromAssemblies
});

// 新的方式,将注入和验证分离
//builder.Services.AddValidatorsFromAssemblyContaining<LoginByUserNamePwdRequestValidator>();
builder.Services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
builder.Services.AddFluentValidationAutoValidation();

如果没有注入服务可以手动调用,一般不推荐

var validator = new Login2RequestValidator();
ValidationResult res = validator.Validate(request);
if (!res.IsValid)
{
    return BadRequest(res.Errors.ToString());
    //return StatusCode((int)HttpStatusCode.BadRequest, string.Join("", res.Errors));
}

//将验证服务注入
builder.Services.AddScoped<IValidator<LoginByUserNamePwdRequest>, UserValidator>();

//在其他类中注入并使用
public class UserService
{
    private readonly IValidator<LoginByUserNamePwdRequest> _validator;

    public UserService(IValidator<LoginByUserNamePwdRequest> validator)
    {
        _validator = validator;
    }

    public async Task DoSomething(LoginByUserNamePwdRequest user)
    {
        var validationResult = await _validator.ValidateAsync(user);
    }
}
  • 编写模型类Login2Request

public record Login2Request(string Email, string Password, string Password2);
  • 编写继承自AbstractValidator的数据校验类

public class Login2RequestValidator: AbstractValidator<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("两次密码必须一致");
    }
}
  • 用Login2Request做Action方法的参数。

FluentValidation + DI

可以在Login2RequestValidator类的构造函数中注入其他需要的服务

  1. 可以通过构造方法来向数据校验类中注入服务

  2. RuleFor(x => x.UserName).NotNull()

.Must(name=>dbCtx.Users.Any(u=>u.UserName== name))

.WithMessage(c => $"用户名{c.UserName}不存在");

  1. RuleFor(x => x.UserName).NotNull()

.MustAsync((name,_) => dbCtx.Users.AnyAsync(u => u.UserName == name))

.WithMessage(c => $"用户名{c.UserName}不存在");

.net内置的数据校验

  1. .NET Core中内置了对数据校验的支持,在System.ComponentModel.DataAnnotations这个命名空间下,比如[Required]、[EmailAddress] 、[RegularExpression]。CustomValidationAttribute、IValidatableObject。

  2. 演示其在ASP.NET Core中请求中的使用。

  3. 内置的校验机制的问题:校验规则都是和模型类耦合在一起,违反“单一职责原则”;很多常用的校验都需要编写自定义校验规则,而且写起来麻烦。


评论