首页 > 其他分享 >学习收-在 .NET 中使用 FluentValidation 进行参数验证

学习收-在 .NET 中使用 FluentValidation 进行参数验证

时间:2022-09-29 14:13:27浏览次数:50  
标签:RuleFor FirstName NotEmpty 验证 FluentValidation UserValidator NET public

安装 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": [
            "您的名字长度已经超出了限制!"
        ]
    }
}

学习收录于微信公众号 半栈程序员

标签:RuleFor,FirstName,NotEmpty,验证,FluentValidation,UserValidator,NET,public
From: https://www.cnblogs.com/xu-fan/p/16741302.html

相关文章

  • Asp.Net Core 过滤器
    前言    过滤器,从我们开始开发Asp.Net应用程序开始,就一直伴随在我们左右;Asp.NetCore提供多种类型的过滤器,以满足多种多样的业务应用场景;并且在Asp.NetCore本身......
  • 【Kubernetes】K8s笔记(三):Kubernetes 中的核心概念 Pod
    目录0.为什么叫Pod1.Pod是Kubernetes中的核心对象2.使用YAML描述Pod3.使用kubectl操作Pod0.为什么叫PodPod这个词原意是“豌豆荚”,后来又延伸出“舱室......
  • Implementing Google Analytics on an ASP.NET website
    ImplementingGoogleAnalyticsonanASP.NETwebsiteGoogleAnalyticsisaserviceofferedbyGooglethatgeneratesdetailedstatisticsaboutawebsite’stra......
  • .net开发平台
    .net开发平台下有三种开发框架.netframework(部分开源)适用于windows系统开发,其中里面包含asp.net  wpf  winform   支持Windows和Web应用程序。现在,您可......
  • Log4net配置与使用
    Log4net的优点:几乎所有的大型应用都会有自己的用于跟踪调试的API。因为一旦程序被部署以后,就不太可能再利用专门的调试工具了。然而一个管理员可能需要有一套强大的日志系......
  • MQTTnet3.1.2 服务端
    usingMQTT;usingMQTTnet.Client;usingMQTTnet.Protocol;usingMQTTnet;usingMQTTnet.Server;usingSystem;usingSystem.Collections.Generic;usingSystem.Te......
  • .NET教程 - 数组(Array)
    更新记录转载请注明出处:2022年9月29日发布。2022年9月28日从笔记迁移到博客。System.Array说明Array类型是所有一维和多维数组的基类System.Array类型实现了ILi......
  • .NET教程 - 数值 & 随机数(Number & Random)
    更新记录转载请注明出处:2022年9月29日发布。2022年9月28日从笔记迁移到博客。System.Numerics.BigIntegerBigInteger说明BigInteger类型用于表示任意大的整数数......
  • 聊聊 dotnet 7 对 bool 与字符串互转的底层性能优化
    本文也叫跟着StephenToub大佬学性能优化系列。大家都知道在.NET7有众多的性能优化,其中就包括了对布尔和字符串互转的性能优化。在对布尔和字符串的转换的性能优化上......
  • kubenetes之pod
    创建一个基础的podvimnginx.yamlapiVersion:v1#必选,API的版本号kind:Pod#必选,类型Podmetadata:#必选,元数据name:nginx#必选,符合RFC1035规范的Pod......