FluentValidation 支持与 ASP.NET Core 2.1 或3.1集成(建议使用3.1)。启用后,MVC将使用 FluentValidation 来验证由模型绑定基础结构传递到控制器操做中的对象。前端
要启用MVC集成,您须要 FluentValidation.AspNetCore 经过安装适当的NuGet软件包来添加对程序集的引用。ide
安装完成后,您须要经过在 AddFluentValidation 方法在 Startup 类中的 ConfigureServices 方法中注册服务。函数
public void ConfigureServices(IServiceCollection services) {
services.AddMvc().AddFluentValidation().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
为了使验证生效还须要再 ConfigureServices 中依赖注入咱们的验证器。spa
services.AddTransient<IValidator<Customer>, CustomerValidator>();
不过这样一个个注册太麻烦了,因此有一个批量注册的方法 RegisterValidatorsFromAssemblyContaining 经过这个方法能够注册特定程序集中的全部的验证器。这将自动查找从其继承 AbstractValidator 并在容器中注册的全部公共非抽象类型(不支持开放的泛型)。以下所示建立一个验证器和一个验证器接口,相应的类我就不建立了。code
public class CustomerValidator : AbstractValidator<Customer> , IValidator { public CustomerValidator() { RuleFor(t => t.Name).NotEmpty(); } } public interface IValidator{}
以后在 Startup 类中的 ConfigureServices 方法中使用 RegisterValidatorsFromAssemblyContaining 注册 IValidator 接口,这样全部继承 IValidator 和 AbstractValidator 的验证器就会所有自动注册了。对象
services.AddMvc().AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<IValidator>()).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
自动注册的验证器是以 Transient 的形式注册的而不是 Singleton 。若是您不想注册特定的验证器类型,则可使用过滤器回调将其排除,以下所示就排除了CustomerValidator验证器:blog
services.AddMvc().AddFluentValidation(fv => fv.RegisterValidatorsFromAssemblyContaining<IValidator>(discoveredType => discoveredType.ValidatorType != typeof(CustomerValidator))).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
直接用原来的 ModelState.IsValid 就能够了。继承
public IActionResult Create(Customer customer) { customer = new Customer(); CustomerValidator validationRules = new CustomerValidator(); if (!ModelState.IsValid) return Content("失败了"); return View(); }
运行应用程序时,还能够选择对子属性启用隐式验证。启用此功能后,无需使用来指定子验证器 SetValidator,MVC的验证基础结构将递归地尝试自动为每一个属性查找验证器。能够经过设置 ImplicitlyValidateChildProperties 为true来完成:递归
services.AddMvc().AddFluentValidation(fv => { fv.ImplicitlyValidateChildProperties = true; });
请注意,若是启用此行为,则不该将其 SetValidator 用于子属性,不然验证程序将执行两次。接口
有时您可能须要手动验证 MVC 项目中的对象,在这种状况下, 咱们能够将验证结果复制到 MVC 的 ModelState 字典中,即可用于前端错误提示。
public ActionResult DoSomething() { var customer = new Customer(); var validator = new CustomerValidator(); var results = validator.Validate(customer); results.AddToModelState(ModelState, null); return View(); }
AddToModelState 方法是做为扩展方法实现的, 须要引用 FluentValidation 命名空间,请注意, 第二个参数是可选的模型名称前缀, 该参数可设置对象属性在 ModelState 字典中的前缀。
您可使用 CustomizeValidatorAttribute 为模型指定验证程序,也支持为验证器指定规则集。
public ActionResult Save([CustomizeValidator(RuleSet="MyRuleset")] Customer cust) { // ... }
这至关于为验证指定规则集,等同于将规则集传递给验证程序:
var validator = new CustomerValidator(); var customer = new Customer(); var result = validator.Validate(customer, ruleSet: "MyRuleset");
该属性还可用于调用单个属性的验证:
public ActionResult Save([CustomizeValidator(Properties="Surname,Forename")] Customer cust) { // ... }
这至关于对验证程序指定特定属性,其它属性将不被验证:
var validator = new CustomerValidator(); var customer = new Customer(); var result = validator.Validate(customer, properties: new[] { "Surname", "Forename" });
也可使用 CustomizeValidatorAttribute 特性跳过某些类型的验证。
public ActionResult Save([CustomizeValidator(Skip=true)] Customer cust) { // ... }
您可使用拦截器进一步自定义验证过程,拦截器必须实现 FluentValidation.Mvc 命名空间中的 IValidatorInterceptor 接口:
public interface IValidatorInterceptor { ValidationContext BeforeMvcValidation(ControllerContext controllerContext, ValidationContext validationContext); ValidationResult AfterMvcValidation(ControllerContext controllerContext, ValidationContext validationContext, ValidationResult result); }
此接口有两个方法:BeforeMvcValidation 和 AfterMvcValidation,分别可拦截验证前和验证后的过程。除了在验证程序类中直接实现此接口外, 咱们还能够在外部实现该接口, 经过 CustomizeValidatorAttribute 特性指定拦截器:
public ActionResult Save([CustomizeValidator(Interceptor=typeof(MyCustomerInterceptor))] Customer cust) { //... }
在这种状况下, 拦截器必须是一个实现 IValidatorInterceptor 接口,并具备公共无参数构造函数的类。请注意, 拦截器是高级方案,大多数状况下, 您可能不须要使用拦截器, 但若是须要, 能够选择它。
默认状况下 FluentValidation 不会为客户端生成基于规则集的验证代码, 但您能够经过 RuleSetForClientSideMessagesAttribute 为客户端指定规则集。
[RuleSetForClientSideMessages("MyRuleset")] public ActionResult Index() { return View(new PersonViewModel()); }
也能够在控制器中使用 SetRulesetForClientsideMessages 扩展方法 (须要引用 FluentValidation 命名空间)为客户端指定规则集。
public ActionResult Index() { ControllerContext.SetRulesetForClientsideMessages("MyRuleset"); return View(new PersonViewModel()); }