【问题标题】:Using FluentValidation to validate mutually exclusive fields使用 FluentValidation 验证互斥字段
【发布时间】:2015-03-31 19:14:17
【问题描述】:

我正在尝试使用 FluentValidation 验证三个字段中只有一个具有值。

RuleFor(x => x.Date1)
            .Must(x => !x.HasValue)
            .When(x => x.Date2.HasValue || x.Date3.HasValue)
            .WithMessage("Select only one of Date 1, Date 2 and Date 3");

这在其他 2 个日期重复。正如所料,这会根据匹配的规则生成消息。

还涉及其他规则,那么有没有办法执行其他规则但在这三个规则中的第一个失败?我已经看到可以在哪里设置 CascadeMode.StopOnFirstFailure 全局,但我希望这三个之外的其他规则能够像目前一样工作。

【问题讨论】:

  • 将三个规则合并到一个 .Custom(...) 规则中。

标签: c# fluentvalidation


【解决方案1】:

我决定走另一条路。感觉很优雅,但我会知道它是否通过了代码审查。

我创建了一个新属性

    public IEnumerable<DateTime?> MutuallyExclusiveDates
    {
        get
        {
            return new List<DateTime?>()
            {
                Date1,
                Date2,
                Date3
            };

        }
    }

然后我添加了这条规则

 RuleFor(x => x.MutuallyExclusiveDates)
            .Must(x => x.Count(d => d.HasValue) <= 1)
            .WithMessage("Select only one of Date 1, Date 2 and Date 3");

【讨论】:

  • 你不能用返回包含三个日期的列表的 lambda 替换在 RuleFor(...) 调用中选择属性值的 lambda 吗?然后你可以删除额外的属性。
  • 昨天是我第一次使用 FluentValidation,所以在尝试了一些失败的方法之后,这个方法奏效了。我喜欢模型可以很容易地用所涉及的日期更新的事实。
【解决方案2】:

使用 xor 为所有 3 个简单的规则。不需要额外的属性。如果您想强制至少有一个值,请取出除非。

 RuleFor(x => x).Cascade(CascadeMode.StopOnFirstFailure)
     .Must(x => (x.date1.HasValue ^ x.date2.HasValue) ^ x.date3.HasValue)
     .Unless(x => !x.date1.HasValue && !x.date2.HasValue && !x.date3.HasValue)
     .WithMessage("Select only one of Date 1, Date 2 and Date 3");

【讨论】:

    【解决方案3】:

    我会使用类似的东西

    RuleFor(x => x).Must(ValidateDates).WithName("something");
    
    <snip/>
    
    private bool ValidateDates(SomeRequest request)
    {
       //perform logic and return true/false;
    }
    

    在ValidateDates 方法中,您可以访问完整的请求。

    有关使用Must 进行复杂验证的更多示例,请查看这篇文章 - http://nodogmablog.bryanhogan.net/2015/04/complex-model-validation-using-fluent-validation/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多