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

如果使用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"

在.NET Core 中使用 FluentValidation 进行规则验证相关推荐

  1. 如何使用Google Authenticator在ASP.NET Core中设置两因素身份验证

    介绍 (Introduction) In this article, we are going to learn how to perform two-factor authentication in ...

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

    本篇博文中展示了如何在ASP.NET Core应用程序中设置IP白名单验证的3种方式. 你可以使用一下3种方式: 使用中间件检查每个请求的远程IP地址 使用Action过滤器为指定的Controlle ...

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

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

  4. 在asp.net core中使用的验证框架FluentValidation

    FluentValidation在asp.net core中怎么使用? 先安装包. Install-Package FluentValidation.AspNetCore 和上一篇的实体类和验证类一样 ...

  5. transactionscope 中的异步 处理 异常_.NET Core中TransactionScope事务处理方法介绍及注意事项...

    作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/10170712.html 今天在写CzarCms的UnitOfWork的使用使用到了这个Transacti ...

  6. .ASP NET Core中缓存问题案例

    本篇博客中,我将描述一个关于会话状态(Session State)的问题, 这个问题我已经被询问了好几次了. 问题的场景 创建一个新的ASP.NET Core应用程序 一个用户在会话状态中设置了一个字 ...

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

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

  8. ASP.NET Core 中的规约模式(Specification Pattern )——增强泛型仓储模式

    原文链接:https://codewithmukesh.com/blog/specification-pattern-in-aspnet-core/ 在本文中,我们将讨论在 ASP.NET Core ...

  9. Api网关Kong集成Consul做服务发现及在Asp.Net Core中的使用

     1622219047536 写在前面   Api网关我们之前是用 .netcore写的 Ocelot的,使用后并没有完全达到我们的预期,花了些时间了解后觉得kong可能是个更合适的选择. 简单说下 ...

最新文章

  1. hihoCoder1678 版本号排序
  2. 全国计算机二级vb得分技巧,全国计算机等级考试二级VB笔试各题型答题技巧(2)...
  3. 使用refs获取节点_闲庭信步聊前端 - 原来你是这样的Refs
  4. 微软P2V工具之Disk2VHD
  5. 设计代码说明什么是多态性?如何实现多态?(代码中要写注释解释)_狗屎一样的代码!快,重构我...
  6. WEB消息提醒实现之二 实现方式-websocket实现方式
  7. MYSQL正式环境主从复制(不锁表,不停服务)
  8. fastjson.toJSONString字段排序
  9. 跳转到系统挑选铃声的页面
  10. lazy load 图片延迟加载 跟随滚动条
  11. PostgreSQL 主从差异查看
  12. 关于SQL的重复记录问题
  13. 课程设计之图书管理系统C#实现
  14. 求和问题总结(leetcode 2Sum, 3Sum, 4Sum, K Sum)
  15. mac(苹果)电脑有网,浏览器上不了网了,打开不了网页,但是微信、QQ正常使用,如何解决?
  16. Bibexcel 与 Pajek 基本分析
  17. 计算机ip地址错误,网络ip地址怎么修复_ip地址错误的修复步骤-win7之家
  18. P4编程环境安装(ubuntu16.04,p4c+bmv2+mininet+PI+tutorial)
  19. [Linux]生产者消费者模型(基于BlockQueue的生产者消费者模型 | 基于环形队列的生产者消费者模型 | 信号量 )
  20. linux中内核4c,一台Linux服务器(4C8G配置)可以负载百万个连接?

热门文章

  1. html5/css3响应式布局介绍
  2. Cordova入门系列(三)Cordova插件调用 转发 https://www.cnblogs.com/lishuxue/p/6018416.html...
  3. Python 循环删除指定文件夹下所有的.longtian类型文件
  4. UVa 1639 (期望) Candy
  5. 【转】SQL SERVER 存储过程学习笔记
  6. 最后的代课老师———漆红玉[转]
  7. .text 0.958之间居的中文汉化下载
  8. python倒三角形粉色填充笔的形状海龟_Python001-Turtle(海龟绘图)详解
  9. Mysql-高可用集群[MyCat中间件使用](三)
  10. python:继承日志模块生成自定义日志