使用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
相关产品推荐
相关产品推荐

