在.NET Core 中使用 FluentValidation 进行规则验证

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

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

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

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

安装 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#p-6.5.1","title": "One or more validation errors occurred.","status": 400,"traceId": "|c4523c02-4899b7f3df86a629.","errors": { "FirstName": ["您的名字长度已经超出了限制!"]}
}

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

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

最后

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

References

[1] Github: "https://github.com/FluentValidation/FluentValidation"
[2] https://www.code4it.dev/blog/fluentvalidation: "https://www.code4it.dev/blog/fluentvalidation"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/304642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

scrcpy投屏_安卓投屏利器——PC一键控制多台手机

点击关注&#xff0c;我们共同每天进步一点点&#xff01;之前给大家介绍了投屏开源工具scrcpy(Scrcpy投屏&#xff0c;在电脑上流畅操控你的手机&#xff01;)&#xff0c;今天要介绍的投屏工具是在scrcpy的基础上进行了二次开发&#xff0c;使用更加友好。《安卓投屏》基于Gi…

【干货】通俗理解神经网络中激活函数作用

推荐阅读时间8min~13min主要内容&#xff1a;通俗理解激活函数&#xff0c;主要来自我在学习会的slides&#xff0c;讲解了激活函数的非线性能力和组合特征的作用下面我分别对激活函数的两个作用进行解释。1加入非线性因素&#xff0c;解决非线性问题好吧&#xff0c;很容易能够…

创建第一个WCF程序

WCF的三大核心是ABC A代表Address-where&#xff08;对象在哪里&#xff09; B代表Binding-how&#xff08;通过什么协议取得对象&#xff09; C代表Contact&#xff08;契约&#xff09;-what&#xff08;定义的对象是什么&#xff0c;如何操纵&#xff09; 创建一个空的解决方…

.NET微服务最佳实践eShopOnContainers

本文翻译自微软Docs&#xff0c; 内嵌译者多年使用的参悟&#xff0c;如理解有误&#xff0c;请不吝赐教。微软与社区专家合作&#xff0c;开发了功能齐全的云原生微服务示例应用eShopOnContainers。该应用旨在展示使用.NET、Docker以及可选的Azure&#xff0c;Kubernetes技术来…

正态分布为什么常见?

统计学里面&#xff0c;正态分布&#xff08;normal distribution&#xff09;最常见。男女身高、寿命、血压、考试成绩、测量误差等等&#xff0c;都属于正态分布。>>>> 作者&#xff1a; 阮一峰以前&#xff0c;我认为中间状态是事物的常态&#xff0c;过高和过低…

Python 写各大聊天系统的屏蔽脏话功能原理

来源&#xff1a;Cookie-Fei www.cnblogs.com/cookie1026/p/6121363.html突然想到一个视频里面弹幕被和谐的一满屏的*号觉得很有趣&#xff0c;然后就想用python来试试写写看&#xff0c;结果还真玩出了点效果&#xff0c;思路是首先你得有一个脏话存放的仓库好到时候检测&…

RHEL4- SAMBA服务(四)在x-window下图形界面简单搭建samba服务器

RHEL4- SAMBA服务&#xff08;四&#xff09;在x-window下图形界面简单搭建samba服务器在《RHEL4- SAMBA服务&#xff08;一&#xff09;samba服务的安装与启动》中我讲了如何安装和启动samba服务器&#xff0c;这一篇我来说一说如何使用图形界面配置简单的samba服务&#xff0…

mvc identity连接mysql_asp.net MVC5,如何使用mysql数据库,使用MVC框架中自带的identity用户验证体系...

问题如题现在很多时候&#xff0c;即使是.net项目&#xff0c;我们用的数据库也未必时是 SQL Server了。但很多VS 自带的框架(如MVC 、WebAPI等框架)中的示例自带的仍然是默认Sql Server的&#xff0c;而且并不一定好改成别的数据库。这有时候就很苦恼。比如.net MVC框架中自带…

Dapr 知多少 | 分布式应用运行时

IntroDapr 官方团队已于最近&#xff08;2021.2.17&#xff09;正式发布Dapr v1.0&#xff0c;Dapr已正式生产可用&#xff0c;可以部署到自托管环境或 Kubernetes 集群。对于绝大多数开发者来说&#xff0c;想必对Dapr只是有所耳闻&#xff0c;而具体是什么&#xff08;What&a…

使用.NET中的XML注释(一) -- XML注释标签讲解

一.摘要 .Net允许开发人员在源代码中插入XML注释&#xff0c;这在多人协作开发的时候显得特别有用。 C#解析器可以把代码文件中的这些XML标记提取出来&#xff0c;并作进一步的处理为外部文档。 这篇文章将展示如何使用这些XML注释。 在项目开发中&#xff0c;很多人并不乐意写…

mysql tddl_TDDL思考总结

单机数据库分布式数据库TDDL原理与最佳实践1. 数据库的结构1.1. KV存储(id是K)1.2. B树与红黑树B树的特点是叶子节点是块状&#xff0c;一个叶子里面有多个数据&#xff0c;相邻数据是存在一起的&#xff0c;123&#xff0c;456起等&#xff0c;而磁盘也是按块的&#xff0c;B树…

c# winform中窗体切换后释放及防止重复生成

问题1&#xff1a;窗体切换后如何关闭,并释放资&#xff1f;c# winform中,2个窗体,form1和form2,互相切换的时候执行this.Hide(); Form2 form2 new Form2();form2.Show();此时你会发现当Form2显现时&#xff0c;Form1隐藏了&#xff0c;但当你关闭Form2时&#xff0c;其进程并…

2018程序员必备碎片化学习工具(年度精选)

2017马上就要过去了&#xff0c;2018来了。工作、生活节奏超快的今天&#xff0c;想要不断提升自我&#xff0c;碎片化阅读学习是你最佳的选择&#xff0c;如果你有一颗学习的心&#xff0c;那这些学习型的公众号&#xff0c;绝对会让你受益匪浅。小编为你精选了技术领域几个精…

mfc 找到字符串中字符_[LeetCode] 467. 环绕字符串中唯一的子字符串

题目链接&#xff1a; https://leetcode-cn.com/problems/unique-substrings-in-wraparound-string难度&#xff1a;中等通过率&#xff1a;35.6%题目描述:把字符串 s 看作是"abcdefghijklmnopqrstuvwxyz"的无限环绕字符串&#xff0c;所以 s 看起来是这样的&#xf…

ntopng mysql_网络流量监控工具与分析Ntop和Ntopng

Ntop工具NtopNtop是一种监控网络流量工具&#xff0c;用ntop显示网络的使用情况比其他一些网络管理软件更加直观、详细。Ntop甚至可以列出每个节点计算机的网络带宽利用率。Ntop工作方式1. 命令行界面2. web界面Ntop的功能1. 可以自动从网络中获取有用的信息2. 可以将获取的数据…

一文读懂背包问题

转自&#xff1a;刘毅https://www.61mon.com/index.php/archives/188/问题展开有 N 件物品和一个容量为 V 的背包。第 i 件物品的体积是 Ci&#xff0c;其价值是 Wi。求解&#xff0c;在不超过背包容量情况下&#xff0c;将哪些物品装入背包可使价值总和最大。基本思路这是最基…

小米造车是智能手机进入红海后的突围之举

日前&#xff0c;媒体报道小米已确定造车&#xff0c;并视其为战略级决策。此前&#xff0c;雷静曾多次考虑造车&#xff0c;但未下定决心&#xff0c;而是选择了投资蔚来和小鹏&#xff0c;而且并未占多少股权&#xff0c;小米在两家公司上市时的持股份额均不到 5%&#xff0c…

群论的创立:两个少年天才的接力

我们生活的世界中&#xff0c;美丽的对称无处不在。不过喜欢认死理的数学家&#xff0c;则硬要用他们独特的语言来定义对称。在数学上&#xff0c;对称与群相关联。随着数论、代数方程和几何等研究方向的发展&#xff0c;“群论”这个无比重要的数学领域被开创建立。而这一伟大…

普通程序员转型深度学习指南

AI领域人才奇缺&#xff0c;炙手可热的AI专业应届生年薪30万起步&#xff0c;AI毕业生基本不用找工作&#xff0c;都已经被企业早早预定。AI人才究竟有多紧缺&#xff1f;据腾讯研究院《全球人工智能人才白皮书》报告数据&#xff0c;目前全球AI领域人才仅约30万&#xff0c;全…

sm缩写代表什么意思_pe、PE在电气有代表什么意思,你发现没有,电气技术很有意思...

pe、pe、pe这些是什么意思解说1&#xff0c;听小课堂电小二跟你讲PE是Protecting Earthing的缩写&#xff0c;简体中文名称称之为“保护导体”&#xff0c;也就是我们通常所说的“地线”&#xff0c;我国规定PE线为黄绿双色线 。1.PE线的应用PE线是专门用于将电气装置外露导电部…