You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Fluent Validation实现UpdateRequest记录类的属性非空关联校验

使用Fluent Validation实现UpdateRequest记录类的属性非空关联校验

嘿,我懂你现在的需求啦——你有一个C#的记录类,想要用Fluent Validation实现一个关联校验:只要三个属性里有一个被赋值了,另外两个也必须都有值,不能只填部分对吧?先把你的UpdateRequest记录类再明确下:

public record UpdateRequest
{
    public int? Prop1 { get; init; }
    public int? Prop2 { get; init; }
    public int? Prop3 { get; init; }
}

这个需求的核心其实可以拆解成:要么三个属性全为空,要么三个全有值——只要打破这个规则,校验就不通过。接下来给你两种实现方式,你可以根据自己的喜好选:


方式一:分场景精准校验(带个性化错误提示)

这种方式会针对每个属性的情况单独校验,错误提示也更具体,用户能一眼知道是哪个属性没配合提供值:

using FluentValidation;

public class UpdateRequestValidator : AbstractValidator<UpdateRequest>
{
    public UpdateRequestValidator()
    {
        // 当Prop1有值时,强制要求Prop2和Prop3也必须有值
        When(x => x.Prop1.HasValue, () =>
        {
            RuleFor(x => x.Prop2).NotNull().WithMessage("当提供Prop1的值时,必须同时提供Prop2的值");
            RuleFor(x => x.Prop3).NotNull().WithMessage("当提供Prop1的值时,必须同时提供Prop3的值");
        });

        // 当Prop2有值时,强制要求Prop1和Prop3也必须有值
        When(x => x.Prop2.HasValue, () =>
        {
            RuleFor(x => x.Prop1).NotNull().WithMessage("当提供Prop2的值时,必须同时提供Prop1的值");
            RuleFor(x => x.Prop3).NotNull().WithMessage("当提供Prop2的值时,必须同时提供Prop3的值");
        });

        // 当Prop3有值时,强制要求Prop1和Prop2也必须有值
        When(x => x.Prop3.HasValue, () =>
        {
            RuleFor(x => x.Prop1).NotNull().WithMessage("当提供Prop3的值时,必须同时提供Prop1的值");
            RuleFor(x => x.Prop2).NotNull().WithMessage("当提供Prop3的值时,必须同时提供Prop2的值");
        });
    }
}

方式二:整体规则校验(简洁高效)

如果不需要太细分的错误提示,只想统一提示“要么全填要么全不填”,那可以用这种更紧凑的写法,直接校验整体逻辑:

using FluentValidation;

public class UpdateRequestValidator : AbstractValidator<UpdateRequest>
{
    public UpdateRequestValidator()
    {
        RuleFor(x => x)
            .Must(request => 
                // 满足两个条件之一:三个全空,或者三个全有值
                (!request.Prop1.HasValue && !request.Prop2.HasValue && !request.Prop3.HasValue) 
                || (request.Prop1.HasValue && request.Prop2.HasValue && request.Prop3.HasValue))
            .WithMessage("请同时提供所有属性的值,或者都不提供");
    }
}

最后给你举个使用验证器的例子,这样你能直接跑起来测试:

// 实例化验证器
var validator = new UpdateRequestValidator();

// 测试1:只填一个属性,校验失败
var badRequest = new UpdateRequest { Prop1 = 10 };
var badResult = validator.Validate(badRequest);
Console.WriteLine(badResult.IsValid); // 输出: False
Console.WriteLine(string.Join("\n", badResult.Errors.Select(e => e.ErrorMessage)));

// 测试2:三个属性都填,校验通过
var goodRequest = new UpdateRequest { Prop1 = 10, Prop2 = 20, Prop3 = 30 };
var goodResult = validator.Validate(goodRequest);
Console.WriteLine(goodResult.IsValid); // 输出: True

// 测试3:三个都不填,校验通过
var emptyRequest = new UpdateRequest();
var emptyResult = validator.Validate(emptyRequest);
Console.WriteLine(emptyResult.IsValid); // 输出: True

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 13:15:31