如何在FluentValidation中实现OR条件的属性验证?
问题:FluentValidation中实现OR逻辑的简洁方式
需求明确:
- 当
EquipmentId > 0时,ActualEquipmentTypeId必须匹配FirstRequestedEquipmentTypeId或SecondRequestedEquipmentTypeId - 若两个请求类型都与实际类型不匹配,返回验证错误
尝试过两种写法都无效:
第一种写法中.Or不是FluentValidation的有效语法:
public class BookingEquipmentModelValidator : AbstractValidator<BookingEquipmentModel> { public BookingEquipmentModelValidator() { RuleFor(be => be.BookingId).GreaterThan(0); RuleFor(be => be.BookingSlotId).GreaterThan(0); RuleFor(be => be.GeneralVentSetting).MaximumLength(50); RuleFor(be => be.Comments).MaximumLength(254); RuleFor(be => be.SealNumber).MaximumLength(15); When(be => be.EquipmentId > 0, () => { RuleFor(be => be.ActualEquipmentTypeId).Equals(be => be.FirstRequestedEquipmentTypeId).Or .Equals(be => be.SecondRequestedEquipmentTypeId).WithMessage("No Match on either Req1 or Req2"); }); } }
第二种写法逻辑错误,无法正确触发验证:
When(be => be.EquipmentId is > 0, () => { RuleFor(be => be.ActualEquipmentTypeId != be.SecondRequestedEquipmentTypeId && be.ActualEquipmentTypeId != be.FirstRequestedEquipmentTypeId).Equals(true); });
希望找到无需冗余代码的简洁实现方式。
简洁解决方案
使用Must方法结合Lambda表达式直接实现OR逻辑,这是最直接的方式:
public class BookingEquipmentModelValidator : AbstractValidator<BookingEquipmentModel> { public BookingEquipmentModelValidator() { RuleFor(be => be.BookingId).GreaterThan(0); RuleFor(be => be.BookingSlotId).GreaterThan(0); RuleFor(be => be.GeneralVentSetting).MaximumLength(50); RuleFor(be => be.Comments).MaximumLength(254); RuleFor(be => be.SealNumber).MaximumLength(15); When(be => be.EquipmentId > 0, () => { RuleFor(be => be.ActualEquipmentTypeId) .Must((model, actualTypeId) => actualTypeId == model.FirstRequestedEquipmentTypeId || actualTypeId == model.SecondRequestedEquipmentTypeId) .WithMessage("No Match on either Req1 or Req2"); }); } }
说明
Must方法支持同时接收当前属性值和整个模型实例,让你可以轻松对比多个属性间的关系,完美实现OR逻辑,代码简洁且易读。
内容的提问来源于stack exchange,提问作者Rob Ainscough
相关产品推荐
相关产品推荐

