[英]FluentValidation: Comparing a value with an aggregate of values?
I find FluentValidation straightforward when making simple rules for properties on a single class, but as soon as I need to compare values from collections (eg a List<T>
property), it gets super-hairy. 当为单个类的属性制定简单规则时,我发现FluentValidation很简单,但是一旦我需要比较集合中的值(例如List<T>
属性),它就会变得很冗长。 Assume the follwing two minimal classes: 假设以下两个最小类:
public class PurchaseOrder
{
public List<LineItem> LineItems { get; set; }
public decimal Total { get; set; }
public PurchaseOrder()
{
LineItems = new List<LineItem>();
}
}
public class LineItem
{
public decimal Price { get; set; }
}
And this class: 和这个类:
class Program
{
static void Main(string[] args)
{
PurchaseOrder order = new PurchaseOrder();
order.LineItems.Add(new LineItem() { Price = 12m });
order.LineItems.Add(new LineItem() { Price = 14m });
order.Total = 26m;
PurchaseOrderValidator validator = new PurchaseOrderValidator();
ValidationResult result = validator.Validate(order);
}
}
How would PurchaseOrderValidator
look like to make sure that the sum of all LineItem.Price
equals the PurchaseOrder.Total
? PurchaseOrderValidator
将如何确保所有LineItem.Price
的总和等于PurchaseOrder.Total
? Here's a stub (although I'm not sure Must()
is the way to go): 这是一个存根(尽管我不确定Must()
是不是要走的路):
public class PurchaseOrderValidator : AbstractValidator<PurchaseOrder>
{
public PurchaseOrderValidator()
{
RuleFor(x => x.Total).Must(MatchSumOfLineItems);
}
private bool MatchSumOfLineItems(decimal arg)
{
return true;
}
}
Just create validation method that takes PurchaseOrder
as input and do whatever you want with it 只需创建将PurchaseOrder
用作输入的验证方法,然后对其执行任何操作即可
public class PurchaseOrderValidator : AbstractValidator<PurchaseOrder>
{
public PurchaseOrderValidator()
{
RuleFor(x => x).Must(MatchSumOfLineItems);
}
private bool MatchSumOfLineItems(PurchaseOrder arg)
{
return arg.Total == arg.LineItems.Sum(i => i.Price);
}
}
or if you want to add validation specifically for Total
property you can use another Must
overload accepts Func<decimal, PurchaseOrder, bool>
或者,如果您要为Total
属性专门添加验证,则可以使用另一个Must
重载接受Func<decimal, PurchaseOrder, bool>
public class PurchaseOrderValidator : AbstractValidator<PurchaseOrder>
{
public PurchaseOrderValidator()
{
RuleFor(x => x.Total).Must(MatchSumOfLineItems);
}
private bool MatchSumOfLineItems(PurchaseOrder order, decimal sum)
{
return sum == order.LineItems.Sum(i => i.Price);
}
}
Why not use .Equal()
为什么不使用.Equal()
public class PurchaseOrderValidator : AbstractValidator<PurchaseOrder>
{
public PurchaseOrderValidator()
{
RuleFor(x => x.Total).Equal(x => x.LineItems.Sum(item => item.Price));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.