ZetCode

C# FluentValidation

最后修改于 2023 年 7 月 5 日

本文简要介绍了使用 FluentValidation 库在 C# 中进行数据验证。

FluentValidation 是一个 .NET 验证库。 它使用流畅接口和 lambda 表达式来构建强类型验证规则。

$ dotnet add package FluentValidation

我们将包添加到项目中。

C# FluentValidation 简单示例

以下是一个使用 FluentValidation 的简单示例。

Program.cs
using FluentValidation;

var validator = new UserValidator();
var u1 = new User("John Doe", "gardener");
var u2 = new User("Roger Roe", "");

var res = validator.Validate(u1);

if (res.IsValid)
{
    Console.WriteLine("instance is valid");
}
else
{
    Console.WriteLine("instance not valid");
}

var res2 = validator.Validate(u2);

if (res2.IsValid)
{
    Console.WriteLine("instance is valid");
}
else
{
    Console.WriteLine("instance not valid");
}


class User
{
    public string Name;
    public string Occupation;

    public User(string Name, string Occupation) =>
        (this.Name, this.Occupation) = (Name, Occupation);

    public override string ToString() =>
        $"User {{ {this.Name} {this.Occupation} }}";
}

class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(user => user.Name).NotEmpty();
        RuleFor(user => user.Occupation).NotEmpty();
    }
}

在该程序中,我们有一个 User 类。 通过我们的验证代码,我们确保用户属性不为空。

class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(user => user.Name).NotEmpty();
        RuleFor(user => user.Occupation).NotEmpty();
    }
}

验证器类继承自 AbstractValidator。 它使用 RuleFor 为其属性定义规则。 在我们的例子中,我们使用内置的 NotEmpty 规则。

var validator = new UserValidator();

我们创建一个 UserValidator 的实例。

var u1 = new User("John Doe", "gardener");
var u2 = new User("Roger Roe", "");

我们创建两个用户对象。

if (res.IsValid)
{
    Console.WriteLine("instance is valid");
}
else
{
    Console.WriteLine("instance not valid");
}

我们使用 IsValid 检查对象的有效性。

$ dotnet run 
instance is valid
instance not valid

C# FluentValidation 错误

验证结果包含 Errors 属性,其中包含验证错误消息。

Program.cs
using FluentValidation;

var validator = new UserValidator();
var u1 = new User("John Doe", "gardener");
var u2 = new User("Roger Roe", "");

var res = validator.Validate(u1);

if (res.IsValid)
{
    Console.WriteLine("instance is valid");
}
else
{
    Console.WriteLine("instance not valid");
    ShowErrors(res);
}

var res2 = validator.Validate(u2);

if (res2.IsValid)
{
    Console.WriteLine("instance is valid");
}
else
{
    Console.WriteLine("instance not valid");
    ShowErrors(res2);
}

void ShowErrors(FluentValidation.Results.ValidationResult res)
{
    foreach (var e in res.Errors)
    {
        Console.WriteLine(e);
    }
}

class User
{
    public string Name;
    public string Occupation;

    public User(string Name, string Occupation) =>
        (this.Name, this.Occupation) = (Name, Occupation);

    public override string ToString() =>
        $"User {{ {this.Name} {this.Occupation} }}";
}

class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(user => user.Name).NotEmpty();
        RuleFor(user => user.Occupation).NotEmpty();
    }
}

在此程序中,我们还显示错误消息。

void ShowErrors(FluentValidation.Results.ValidationResult res)
{
    foreach (var e in res.Errors)
    {
        Console.WriteLine(e);
    }
}

我们定义 ShowErrors 函数,该函数遍历 Errors 属性并将它们显示到控制台。

$ dotnet run 
instance is valid
instance not valid
'Occupation' must not be empty.

C# FluentValidation 自定义错误消息

可以使用 WithMessage 提供自定义错误消息。

Program.cs
using FluentValidation;

var validator = new UserValidator();
var u = new User("Roger Roe", "");

var res = validator.Validate(u);

if (res.IsValid)
{
    Console.WriteLine("instance is valid");
}
else
{
    Console.WriteLine("instance not valid");
    ShowErrors(res);
}

void ShowErrors(FluentValidation.Results.ValidationResult res)
{
    foreach (var e in res.Errors)
    {
        Console.WriteLine(e);
    }
}

class User
{
    public string Name;
    public string Occupation;

    public User(string Name, string Occupation) =>
        (this.Name, this.Occupation) = (Name, Occupation);

    public override string ToString() =>
        $"User {{ {this.Name} {this.Occupation} }}";
}

class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(user => user.Name).NotEmpty()
            .WithMessage("Validation failed: Name field must not be empty");
        RuleFor(user => user.Occupation).NotEmpty()
            .WithMessage("Validation failed: Occupation field must not be empty");
    }
}

在该程序中,我们添加自定义错误消息。

RuleFor(user => user.Name).NotEmpty()
    .WithMessage("Validation failed: Name field must not be empty");
RuleFor(user => user.Occupation).NotEmpty()
    .WithMessage("Validation failed: Occupation field must not be empty");

紧随 NotEmpty 规则之后,我们调用 WithMessage 并传递自定义错误消息。

$ dotnet run
instance not valid
Validation failed: Occupation field must not be empty

C# FluentValidation 链式规则

验证规则可以链接起来。

Program.cs
using FluentValidation;

var validator = new UserValidator();

var u1 = new User();
ValidateUser(u1);

Console.WriteLine("--------------------");

var u2 = new User();
u2.Name = "John Doe";
ValidateUser(u2);

Console.WriteLine("--------------------");

var u3 = new User();
u3.Name = "John Doe";
u3.Occupation = "gar";
ValidateUser(u3);

Console.WriteLine("--------------------");

var u4 = new User();
u4.Name = "John Doe";
u4.Occupation = "gardener";
ValidateUser(u4);

void ValidateUser(User u)
{
    var res = validator.Validate(u);

    if (res.IsValid)
    {
        Console.WriteLine("instance is valid");
    }
    else
    {
        Console.WriteLine("instance not valid");
        ShowErrors(res);
    }
}

void ShowErrors(FluentValidation.Results.ValidationResult res)
{
    foreach (var e in res.Errors)
    {
        Console.WriteLine(e);
    }
}

class User
{
    public string? Name { get; set; }
    public string? Occupation { get; set; }

    public override string ToString() =>
        $"User {{ {this.Name} {this.Occupation} }}";
}

class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(user => user.Name).NotEmpty().MinimumLength(2);
        RuleFor(user => user.Occupation).NotEmpty().MinimumLength(5);
    }
}

在该程序中,我们为我们的属性使用两个规则:NotEmptyMinimumLength

class UserValidator : AbstractValidator<User>
{
    public UserValidator()
    {
        RuleFor(user => user.Name).NotEmpty().MinimumLength(2);
        RuleFor(user => user.Occupation).NotEmpty().MinimumLength(5);
    }
}

在我们的验证类中,我们假设一个名称至少包含两个字母,而职业包含五个字母。

$ dotnet run
instance not valid
'Name' must not be empty.
'Occupation' must not be empty.
--------------------
instance not valid
'Occupation' must not be empty.
--------------------
instance not valid
The length of 'Occupation' must be at least 5 characters. You entered 3 characters.
--------------------
instance is valid

FluentValidation 文档

本文是对 C# FluentValidation 库的快速介绍。

来源

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 C# 教程