ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

.Net Core 使用 FluentValidation

2020-11-12 22:03:35  阅读:225  来源: 互联网

标签:Customer Core 验证 FluentValidation CustomerValidator var new Net public


FluentValidation 支持与 ASP.NET Core 2.1 或3.1集成(建议使用3.1)。启用后,MVC将使用 FluentValidation 来验证由模型绑定基础结构传递到控制器操作中的对象。

要启用MVC集成,您需要 FluentValidation.AspNetCore 通过安装适当的NuGet软件包来添加对程序集的引用。

安装完成后,您需要通过在 AddFluentValidation 方法在 Startup 类中的 ConfigureServices 方法中注册服务。

public void ConfigureServices(IServiceCollection services)
{              
  services.AddMvc().AddFluentValidation().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }

为了使验证生效还需要再 ConfigureServices 中依赖注入我们的验证器。

services.AddTransient<IValidator<Customer>, CustomerValidator>();

自动注册验证器

不过这样一个个注册太麻烦了,所以有一个批量注册的方法 RegisterValidatorsFromAssemblyContaining 通过这个方法可以注册特定程序集中的所有的验证器。这将自动查找从其继承 AbstractValidator 并在容器中注册的所有公共非抽象类型(不支持开放的泛型)。如下所示创建一个验证器和一个验证器接口,相应的类我就不创建了。

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验证器:

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

标签:Customer,Core,验证,FluentValidation,CustomerValidator,var,new,Net,public
来源: https://www.cnblogs.com/xwc1996/p/13966070.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有