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()); }