您现在的位置是:网站首页> 编程资料编程资料
基于.NET的FluentValidation数据验证实现_实用技巧_
2023-05-24
385人已围观
简介 基于.NET的FluentValidation数据验证实现_实用技巧_
学习地址:官方文档,更多更详细的内容可以看官方文档。
FluentValidation 是一个基于 .NET 开发的验证框架,开源免费,而且优雅,支持链式操作,易于理解,功能完善,还是可与 MVC5、WebApi2 和 ASP.NET CORE 深度集成,组件内提供十几种常用验证器,可扩展性好,支持自定义验证器,支持本地化多语言。
要使用验证框架, 需要在项目中添加对 FluentValidation.dll 的引用,支持 netstandard2.0 库和 .NET4.5 平台,支持.NET Core 平台,最简单的方法是使用 NuGet 包管理器引用组件。我这里安装的是9.2.0版本。
Install-Package FluentValidation
若要在 ASP.NET Core 中使用 FluentValidation 扩展,可引用以下包:
Install-Package FluentValidation.AspNetCore
若要在 ASP.NET MVC 5 或 WebApi 2 项目集成, 可以使用分别使用 FluentValidation.Mvc5 和 FluentValidation.WebApi 程序包。
Install-Package FluentValidation.Mvc5 Install-Package FluentValidation.WebApi
创建第一个验证程序
若要为特定对象定义一组验证规则, 您需要创建一个从 AbstractValidator
public class Customer { public int Id { get; set; } public string Surname { get; set; } public string Forename { get; set; } public decimal Discount { get; set; } public string Address { get; set; } } 接下来自定义继承于 AbstractValidator 泛型类的验证器,然后在构造函数中使用 LINQ 表达式编写 RuleFor 验证规则,使验证在。
using FluentValidation; using NetCoreBasicLearning.Entity; namespace NetCoreBasicLearning { public class CustomerValidator : AbstractValidator { public CustomerValidator() { RuleFor(customer => customer.Surname).NotNull(); } } } 若要执行验证程序,我们通过定义好的 CustomerValidator 验证器传入实体类 Customer 即可。
该验证方法返回一个 ValidationResult 对象,表示验证结果,ValidationResult 包含两个属性:IsValid属性是布尔值, 它表示验证是否成功,Errors属性包含相关验证失败的详细信息。
public IActionResult Index(string id) { Customer customer = new Customer(); CustomerValidator validationRules = new CustomerValidator(); ValidationResult validationResult = validationRules.Validate(customer); if (!validationResult.IsValid) { var str = new StringBuilder(); foreach(var t in validationResult.Errors) { str.AppendLine($"属性:{t.PropertyName},错误信息:{t.ErrorMessage}"); } return Content(str.ToString()); } return View(); } 链接规则写法
您可以将对象的同一属性用多个验证程序链在一起,以下代码将验证 Surname 属性不为 Null 的同时且不等于foo字符串。
using FluentValidation; using NetCoreBasicLearning.Entity; namespace NetCoreBasicLearning { public class CustomerValidator : AbstractValidator { public CustomerValidator() { RuleFor(customer => customer.Surname).NotNull().NotEqual("foo"); } } } 引发异常
如果验证失败, 不想返回 ValidationResult 对象,而是想直接抛出异常,可通过调用验证器的 ValidateAndThrow 进行验证。
如果验证失败,将引发一个 ValidationException 类型的异常,这个异常可以被上层程序捕获,并从异常中找到详细错误信息。
Customer customer = new Customer(); CustomerValidator validationRules = new CustomerValidator(); validationRules.ValidateAndThrow(customer);
集合
当针对一个集合进行验证时,只需要定义集合项类型的规则即可,以下规则将对集合中的每个元素运行 NotNull 检查。
public class Customer { public List OtherAddress { get; set; } } public class CustomerValidator : AbstractValidator { public CustomerValidator() { RuleForEach(customer => customer.OtherAddress).NotEmpty(); } } 如果要对list进行进行非空判断可以如下:
public class CustomerValidator : AbstractValidator{ public CustomerValidator() { RuleFor(customer => customer.OtherAddress).NotEmpty(); } }
复杂属性
验证程序可以用于复杂属性,假设您有两个类:客户和地址
public class Customer { public Adress Address { get; set; } } public class Adress { public string City { get; set; } public string Province { get; set; } } 然后定义一个基于地址的 AddressValidator 验证器件:
public class AdressValidator : AbstractValidator{ public AdressValidator() { RuleFor(t => t.City).NotEmpty(); RuleFor(t => t.Province).NotEmpty(); } }
然后定义一个基于客户的 CustomerValidator 验证器件,对地址验证时使用地址验证器。
public class CustomerValidator : AbstractValidator{ public CustomerValidator() { RuleFor(t => t.Address).SetValidator(new AdressValidator()); } }
如果不想要创建另一个验证器可以直接内联定义子规则:
RuleFor(t => t.Address.City).NotEmpty();
另外,还可以在集合属性上使用验证程序,假设客户对象包含地址集合属性:
public class Customer { public List Address { get; set; } } 此验证程序可在 CustomerValidator 中通过 SetCollectionValidator(在8.0版本以前) 方法使用,在8.0版本以及之后被弃用需要使用RuleForEach来验证:
public class CustomerValidator : AbstractValidator{ public CustomerValidator() { RuleForEach(t => t.Address).SetValidator(new AdressValidator()); //RuleFor(x => x.Address).SetCollectionValidator(new AdressValidator());在8.0版本及以后弃用 } }
在编写验证规则时,可以通过 Where 关键字排除或者筛选不需要验证的对象。
public class CustomerValidator : AbstractValidator{ public CustomerValidator() { RuleForEach(t => t.Address).Where(t => !string.IsNullOrEmpty(t.City)).SetValidator(new AdressValidator()); //RuleFor(x => x.Address).SetCollectionValidator(new AdressValidator()).Where(t => !string.IsNullOrEmpty(t.City));在8.0版本及以后弃用 } }
从FluentValidation 8.5开始,您还可以使用以下ChildRules方法在线定义子集合元素的规则,从而不用再定义另一个验证器:
RuleForEach(t => t.Address).ChildRules(adderss => { adderss.RuleFor(t => t.City).NotEmpty(); adderss.RuleFor(t => t.Province).NotEmpty(); }).NotEmpty(); 支持规则集
规则集允许您将验证规则分组在一起,这些规则可以作为一个组一起执行,而忽略其他规则:
我们可以把“姓”和“名”统一加在一个姓名规则集中。
public class CustomerValidator : AbstractValidator{ public CustomerValidator() { RuleSet("Name", () => { RuleFor(t => t.Surname).NotEmpty(); RuleFor(t => t.Forename).NotEmpty(); }); } }
规则集通过一般的 Validate 方法是不会执行验证的,需要用如下方法进行单独的验证,这将复杂的验证器定义分解为较小的部分进行验证,IncludeRuleSets 中可以传入多个规则集名称来执行多个规则集的验证:
Customer customer = new Customer(); CustomerValidator validationRules = new CustomerValidator(); ValidationResult validationResult = validationRules.Validate(customer, options => options.IncludeRuleSets("Name")); 还可以通过 IncludeRulesNotInRuleSet 方法或使用特殊名称“默认”(不区分大小写)来执行验证所有不属于规则集的规则:
ValidationResult validationResult = validationRules.Validate(customer, options =>{ options.IncludeRulesNotInRuleSet(); options.IncludeRuleSets("Name"); } ); 可以通过调用强制执行所有规则,而不管它们是否在规则集中 IncludeAllRuleSets(这等效于using IncludeRuleSets("*"))。
同个类型的多个验证器
一个验证器可以包含多个其他的验证器,只要这些验证器都是验证统一类型的即可。这样就可以拆分验证器,通过不同的需求组合在一起:
public class CustomerValidator : AbstractValidator{ public CustomerValidator() { Include(new CustomerSurnameValidator()); Include(new CustomerForenameValidator()); } } public class CustomerSurnameValidator : AbstractValidator { public CustomerSurnameValidator() { RuleFor(t => t.Surname).NotEmpty(); } } public class CustomerForenameValidator : AbstractValidator { public CustomerForenameValidator() { RuleFor(t => t.Forename).NotEmpty(); } }
继承验证
从FluentValidation 9.2开始,如果您的对象属性作为其他类的基类或接口,则可以为各个子类/实现器设置特定的子验证器,来验证这个属性。我们的类设置如下:
public class Store { public People Peoples { get; set; } } public class Customer : People { public string Address { get; set; } } public class People { public string Name { get; set; } } 验证器如下:
public class StoreValidator : AbstractValidator{ public StoreValidator() { RuleFor(t => t.Peoples).NotNull().SetInheritanceValidator(t => { t.Add (new CustomerValidator()); }); } } public class CustomerValidator : AbstractValidator { public CustomerValidator() { RuleFor(t => t.Address).NotEmpty(); } }
覆盖消息
通过在验证程序上调用 WithMessage 方法, 可以覆盖验证程序的默认验证错误消息。错误提示中,可以通过 {PropertyName} 占位符替换属性名。除了 {PropertyName} 占位符,框架还内置了:{PropertyValue}、{ComparisonValue}、{MinLength}、{MaxLength}和{TotalLength} 占位符,关于更多内置占位符,可以参阅官方文档。
RuleFor(customer => customer.Surname).NotNull().WithMessage("Please ensure you have entered your {PropertyName}"); 验证程序支持通过 WithName 方法来指定属性别名,以下代码输出姓名不能为空。请注意,这仅替换错误消息中属性的名称。当您检查上的Errors集合时ValidationResult,此错误仍将与一个名为的属性相关联Surname。如果要完全重命名该属性,则可以使用OverridePropertyName方法。
RuleFor(customer => customer.Surname).NotNull().WithName("姓名"); 条件
When 和 Unless方法可用于执行满足指定条件情况下的规则,例如只当Surname属性不为空的时候,才执行前面的Name属性的非空验证(Unless和When是相反的所以这边只讲When就行啦!):
RuleFor(t => t.Name).NotEmpty().When(t => !string.IsNullOrEmpty(t.Surname)); <
相关内容
- Nginx配置实现下载文件的示例代码_实用技巧_
- ASP.NetCore使用Swagger实战_实用技巧_
- 详解ASP.NET Core Web Api之JWT刷新Token_实用技巧_
- .NET Core Web APi大文件分片上传研究实现_实用技巧_
- .NET或.NET Core Web APi基于tus协议实现断点续传的示例_实用技巧_
- .NET Core如何进行请求转发的实现_实用技巧_
- ASP.NET Core使用JWT认证授权的方法_实用技巧_
- .NET Core使用Topshelf方式创建Windows服务的全过程记录_实用技巧_
- net core webapi多版本控制与swagger(nswag)配置教程_实用技巧_
- 详解ASP.NET Core 反向代理部署知多少_实用技巧_
点击排行
本栏推荐
