官网: FluentValidation — FluentValidation documentation
基本使用
FluentValidation:用类似于EF Core中Fluent API的方式进行校验规则的配置,也就是我们可以把对模型类的校验放到单独的校验类中。
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类的构造函数中注入其他需要的服务
可以通过构造方法来向数据校验类中注入服务
RuleFor(x => x.UserName).NotNull()
.Must(name=>dbCtx.Users.Any(u=>u.UserName== name))
.WithMessage(c => $"用户名{c.UserName}不存在");
RuleFor(x => x.UserName).NotNull()
.MustAsync((name,_) => dbCtx.Users.AnyAsync(u => u.UserName == name))
.WithMessage(c => $"用户名{c.UserName}不存在");
.net内置的数据校验
.NET Core中内置了对数据校验的支持,在System.ComponentModel.DataAnnotations这个命名空间下,比如[Required]、[EmailAddress] 、[RegularExpression]。CustomValidationAttribute、IValidatableObject。
演示其在ASP.NET Core中请求中的使用。
内置的校验机制的问题:校验规则都是和模型类耦合在一起,违反“单一职责原则”;很多常用的校验都需要编写自定义校验规则,而且写起来麻烦。