不用说,规则验证很重要,无效的参数,可能会导致程序的异常。

如果使用Web API或MVC页面,那么可能习惯了自带的规则验证,我们的控制器很干净:

public class User
{
[Required]
public string FirstName { get; set; } [Required]
public string LastName { get; set; }
}

这种很常见,但是今天我想给你一个更好的替代方案:FluentValidation, 通过这个库,您可以流畅地定义用于对象验证的复杂规则,从而轻松构建和理解验证规则,您可以在 Github 上找到这个项目。

安装 FluentValidation

我新建了一个很简单的.NET Core 的Web API 程序,只有一个接口是用户注册,入参是一个User类, 然后在Nuget中安装 FluentValidation

创建第一个验证

对于要验证的每个类,必须创建其自己的验证器,每个验证器类都必须继承AbstractValidator<T>,其中T是要验证的类,并且所有验证规则都在构造函数中定义,就像这样:

最简单的验证是针对空值,如果要指定FirstName和LastName都不能为空,这个验证器是这样:

public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
RuleFor(x => x.FirstName).NotEmpty();
RuleFor(x => x.LastName).NotEmpty();
}
}

就这些了,您已经创建了第一个验证器,是不是超级简单!

还有一些其他的规则,比如 MinimumLength,MaximumLength和Length,用于验证长度,您可以把多个规则指定到一个字段,就像这样:

public class UserValidator : AbstractValidator<User>
{
public UserValidator()
{
RuleFor(x => x.FirstName).NotEmpty();
RuleFor(x => x.FirstName).MinimumLength(3);
RuleFor(x => x.FirstName).MaximumLength(20); RuleFor(x => x.LastName).NotEmpty();
}
}

验证入参

我们之前已经定义了验证规则,现在开始使用它,您只需要new 一个UserValidator对象,然后调用Validate方法, 它会返回一个对象,其中包含了验证状态和所有没有通过验证的信息。

[HttpPost]
public IActionResult Register(User newUser)
{
var validator = new UserValidator();
var validationResult = validator.Validate(newUser); if (!validationResult.IsValid)
{
return BadRequest(validationResult.Errors.First().ErrorMessage);
} return Ok();
}

如果我运行程序,然后输入一个超长的名字:

{
"FirstName": "赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张",
"LastName": "张"
}

我会收到验证错误:"The length of 'First Name' must be 20 characters or fewer. You entered 24 characters"。

好吧,我不喜欢这个消息,那么你可以自定义错误消息,这很简单,您可以使用 WithMessage 方法。

- RuleFor(x => x.FirstName).MaximumLength(20);
+ RuleFor(x => x.FirstName).MaximumLength(20).WithMessage("您的名字长度已经超出了限制!");

流利验证

你可以把验证规则,改成下边这样:

- RuleFor(x => x.FirstName).NotEmpty();
- RuleFor(x => x.FirstName).MinimumLength(3);
+ RuleFor(x => x.FirstName).NotEmpty().MinimumLength(3);

然后也可以把验证规则应用于其他的属性,就像这样:

public UserValidator()
{
RuleFor(x => x.FirstName)
.MaximumLength(20).WithMessage("您的名字长度已经超出了限制!")
.NotEmpty().MinimumLength(3); RuleFor(x => x.LastName).NotEmpty();
}

常见的验证规则

这个库有很多现成的基本类型验证规则, 对于字符串,您可以使用不同的方法,比如 EmailAddress,IsEnumName(检查值是否在指定的Enum类型中定义)和 InclusiveBetween, 检查该值是否在定义的范围内。

现在,我在User类添加了另外两个字段,Password 和 ConfirmPassword。

Password字段是一个字符串,有效的长度必须在5到15个字符之间,并且要符合正则,为了定义是否满足安全规则,我定义了一个HasValidPassword方法,它会返回一个bool值。

private bool HasValidPassword(string pw)
{
var lowercase = new Regex("[a-z]+");
var uppercase = new Regex("[A-Z]+");
var digit = new Regex("(\\d)+");
var symbol = new Regex("(\\W)+"); return (lowercase.IsMatch(pw) && uppercase.IsMatch(pw) && digit.IsMatch(pw) && symbol.IsMatch(pw));
}

然后在密码验证中使用:

RuleFor(x => x.FirstName)
.MaximumLength(20).WithMessage("您的名字长度已经超出了限制!")
.NotEmpty().MinimumLength(3); RuleFor(x => x.LastName).NotEmpty(); RuleFor(x => x.Password)
.Length(5, 15)
.Must(x => HasValidPassword(x));

还可以简化一些:

RuleFor(x => x.Password)
.Length(5, 15)
- .Must(x => HasValidPassword(x));
+ .Must(HasValidPassword);
}

ConfirmPassword字段的唯一要求是等于Password字段:

RuleFor(x => x.ConfirmPassword)
.Equal(x => x.Password)
.WithMessage("2次密码不一致!");

注入验证器

修改Startup类中的ConfigureServices方法:

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers().AddFluentValidation(); services.AddTransient<IValidator<User>, UserValidator>();
}

注意:这个地方的生命周期是 Transient。

这样,在调用注册接口的时候,会自动进行规则验证:

[HttpPost]
public IActionResult Register(User newUser)
{
return Ok();
}

然后,我们再尝试传入参数来调用接口:

{
"FirstName": "赵钱孙李周吴郑王冯陈褚卫蒋沈韩杨朱秦尤许何吕施张",
"LastName": "张"
}

很明显,验证不通过,接口会返回这样的错误信息:

{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "|c4523c02-4899b7f3df86a629.",
"errors": {
"FirstName": [
"您的名字长度已经超出了限制!"
]
}
}

希望对您有帮助,您可以在官方文档中找到更多的用法。

原文链接: https://www.code4it.dev/blog/fluentvalidation

最后

欢迎扫码关注我们的公众号 【全球技术精选】,专注国外优秀博客的翻译和开源项目分享,也可以添加QQ群 897216102

在.NET Core 中使用 FluentValidation 进行规则验证的更多相关文章

  1. 【翻译】asp.net core中使用FluentValidation来进行模型验证

    asp.net core中使用FluentValidation FluentValidation 可以集成到asp.net core中.一旦启用,MVC会在通过模型绑定将参数传入控制器的方法上时使用F ...

  2. 在 ASP.NET Core 中使用 FluentValidation 进行验证

    目录 从 NuGet 安装 FluentValidation 争对 Resource类 建立 FluentValidation 在Startup中对写好的验证进行注册 从 NuGet 安装 Fluen ...

  3. 从零搭建一个IdentityServer——聊聊Asp.net core中的身份验证与授权

    OpenIDConnect是一个身份验证服务,而Oauth2.0是一个授权框架,在前面几篇文章里通过IdentityServer4实现了基于Oauth2.0的客户端证书(Client_Credenti ...

  4. 如何为ASP.NET Core设置客户端IP白名单验证

    原文链接:Client IP safelist for ASP.NET Core 作者:Damien Bowden and Tom Dykstra 译者:Lamond Lu 本篇博文中展示了如何在AS ...

  5. ASP.NET Core WebApi中使用FluentValidation验证数据模型

    原文链接:Common features in ASP.NET Core 2.1 WebApi: Validation 作者:Anthony Giretti 译者:Lamond Lu 介绍 验证用户输 ...

  6. .NET Core中的验证组件FluentValidation的实战分享

    今天有人问我能不能出一篇FluentValidation的教程,刚好今天在实现我们的.NET Core实战项目之CMS的修改密码部分的功能中有用到FluentValidation,所以就以修改用户密码 ...

  7. ASP.NET Core中的依赖注入(2):依赖注入(DI)

    IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...

  8. ASP.NET Core 中文文档 第二章 指南(4.6)Controller 方法与视图

    原文:Controller methods and views 作者:Rick Anderson 翻译:谢炀(Kiler) 校对:孟帅洋(书缘) .张仁建(第二年.夏) .许登洋(Seay) .姚阿勇 ...

  9. ASP.NET Core 中文文档 第三章 原理(13)管理应用程序状态

    原文:Managing Application State 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:高嵩 在 ASP.NET Core 中,有多种途径可以对应用程序的状态进行 ...

随机推荐

  1. Redis分布式锁升级版RedLock及SpringBoot实现

    分布式锁概览 在多线程的环境下,为了保证一个代码块在同一时间只能由一个线程访问,Java中我们一般可以使用synchronized语法和ReetrantLock去保证,这实际上是本地锁的方式.但是现在 ...

  2. Spring MVC—数据绑定机制,数据转换,数据格式化配置,数据校验

    Spring MVC数据绑定机制 数据转换 Spring MVC处理JSON 数据格式化配置使用 数据校验 数据校验 Spring MVC数据绑定机制 Spring MVC解析JSON格式的数据: 步 ...

  3. GeoMesa 环境搭建

    GeoMesa 环境搭建 版本 虚拟机安装 os centos7 Centos安装 CentOS安装Jdk并配置环境变量 hadoop.hbase环境部署 geomesa_hbase部署 geoser ...

  4. 日志框架(Log4J、SLF4J、Logback)--日志规范与实践

    文章目录 一.Log4j 1.1新建一个Java工程,导入Log4j包,pom文件中对应的配置代码如下: 1.2resources目录下创建log4j.properties文件. 1.3输出日志 1. ...

  5. 25.sshd和scp

    1.配置sshd服务 想要使用 SSH 协议来远程管理Linux 系统,则需要部署配置sshd 服务程序.sshd 是基于SSH协议开发的一款远程管理服务程序.   sshd 服务的配置信息保存在/e ...

  6. TCP/IP__TCP协议常用协议默认端口号

  7. vue开发东京买菜,全栈项目,前端django,带手机GPS精准定位,带发票系统,带快递系统,带微信/支付宝/花呗/银行卡支付/带手机号一键登陆,等等

    因为博客园不能发视频,所以,完整的视频,开发文档,源码,请向博主索取 完整视频+开发文档+源码,duanshuiLu.com下载 vue+django手机购物商城APP,带支付,带GPS精准定位用户, ...

  8. UVA 11475 Extend to Palindrome (kmp || manacher || 后缀数组)

    题目链接:点击打开链接 题意:给你一个串,让你在串后面添加尽可能少的字符使得这个串变成回文串. 思路:这题可以kmp,manacher,后缀数组三种方法都可以做,kmp和manacher效率较高,时间 ...

  9. Distinct Substrings SPOJ - DISUBSTR 后缀数组

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  10. 吉哥系列故事――恨7不成妻 HDU - 4507

    题目: 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都讨厌! 吉哥观察了214和77这两个数,发现: 2+1+4=7 7+7=7*2 ...