使用数据注释对属性子集进行强制验证

Mandatory validation for a subset of properties using data annotation

我有一个包含三个字段的 DTO 模型。

[Range(1, 100000)]
public Decimal? BonusRate { get; set; }
[Range(1, 100000)]
public Decimal? BonusGain { get; set; }
[Range(1, 100)]
public Decimal? BonusPercentage { get; set; }

在我的例子中,所有字段都是可选的,但如果设置了一个,则所有其他字段也应设置。我做了一个决定,效果很好,但看起来有点笨拙。

IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
{
    if (BonusRate.HasValue || BonusGain.HasValue || BonusPercentage.HasValue)
        if (!BonusRate.HasValue || !BonusGain.HasValue || !BonusPercentage.HasValue)
             yield return new ValidationResult("message");

}

有人知道更好的方法吗?

if (BonusRate.HasValue == BonusGain.HasValue && BonusGain.HasValue == BonusPercentage.HasValue)

或收集列表中的值并:

var isChecked = list.All(x => (x == list.First()));

经过一些研究和您的建议,我找到了一个通用策略。 您可以免费使用外部包吗?

  1. foolproof 库添加到解决方案
  2. 创建只读 属性 IsGroupRequired 类似于

    public Boolean IsGroupRequired
    {
        get
        {
            return GroupItem1.HasValue == GroupItem2.HasValue
                && GroupItem2.HasValue == GroupItem3.HasValue
                && GroupItemNminus1.HasValue == GroupItemN.HasValue;
        }
    }
    
  3. 为组 GroupItem1..N

  4. 中的每个 属性 分配 [RequiredIfTrue("IsGroupRequired")]

  1. 为您的模型实现一个 IValidatableObject 接口
  2. 编写自己的验证方法

    IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
    {
        if (GroupItem1.HasValue == GroupItem2.HasValue
            && GroupItem2.HasValue == GroupItem3.HasValue
            && GroupItemN.HasValue == GroupItemN+1.HasValue)
                yield return new ValidationResult("Your message goes here");
    }