【问题标题】:checking if parameter is one of 3 values with fluent validation检查参数是否是具有流畅验证的 3 个值之一
【发布时间】:2020-10-20 09:07:00
【问题描述】:

我有一个包含一个字符串属性的类:

public class Bla
{
    public string Parameter { get; set; }
}

我想编写一个自定义 AbstractValidator,它检查 Parameter 是否等于以下字符串之一:

str1, str2, str3

我想这将是一个起点:

RuleFor(x => x.Parameter).Must(x => x.Equals("str1") || x.Equals("str2") || x.Equals("str3")).WithMessage("Please only use: str1, str2, str3");

但我可以链接它并显示错误消息,最好不要对可能性进行硬编码,例如:

Please only use: str1, str2, str3

【问题讨论】:

  • 此时没有机会使用正则表达式?

标签: c# fluentvalidation


【解决方案1】:

您可以使用包含您的条件的列表来执行此操作

List<string> conditions = new List<string>() { str1, str2, str3 };
RuleFor(x => x.Parameter)
  .Must(x => conditions.Contains(x))
  .WithMessage("Please only use: " + String.Join(",", conditions));

【讨论】:

    【解决方案2】:

    用法:

    RuleFor(m => m.Job)
        .In("Carpenter", "Welder", "Developer");
    

    输出:

    工作必须是以下值之一:木匠、焊工或开发人员

    扩展方法:

    public static class ValidatorExtensions
    {
        public static IRuleBuilderOptions<T, TProperty> In<T, TProperty>(this IRuleBuilder<T, TProperty> ruleBuilder, params TProperty[] validOptions)
        {
            string formatted;
            if (validOptions == null || validOptions.Length == 0)
            {
                throw new ArgumentException("At least one valid option is expected", nameof(validOptions));
            }
            else if (validOptions.Length == 1)
            {
                formatted = validOptions[0].ToString();
            }
            else
            {
                // format like: option1, option2 or option3
                formatted = $"{string.Join(", ", validOptions.Select(vo => vo.ToString()).ToArray(), 0, validOptions.Length - 1)} or {validOptions.Last()}";
            }
    
            return ruleBuilder
                .Must(validOptions.Contains)
                .WithMessage($"{{PropertyName}} must be one of these values: {formatted}");
        }
    }
    

    【讨论】:

    • 这很好,我们正在使用它,但是你能想出一种方法来发送比较器吗?我一直在玩它,但一直无法想出办法。
    • 我认为你可以为比较器添加一个参数到In(我们称之为cmprr),然后将.Must(validOptions.Contains)替换为.Must(i =&gt; validOptions.Any(o =&gt; cmprr.Equals(i, o)))
    • 让我知道这是否有帮助,或者你想出了什么。这也可能有用:fluentvalidation.net/custom-validators
    【解决方案3】:

    同意上面 Thomas 的代码 sn-p。我有时喜欢采用另一种方法:如果验证作为一个领域概念有意义,您可以将其分解为一个方法,如下所示:

    RuleFor(x=>x.Parameter).Must(BeAValidParameter).WithMessage("Your parameter must be a valid parameter.");
    
        private static bool BeAValidParameter(string arg)
        {
            return arg.Equals("str1") || arg.Equals("str2") || arg.Equals("str3");
        }
    

    我经常将它用于BeAValidZipCodeBeAValidPhoneNumber 之类的事情,或者一些表达一个业务概念的复杂逻辑。您可以将它与标准验证概念结合使用(例如,避免尝试将所有验证放在一种方法中)。

    【讨论】:

      【解决方案4】:
      RuleFor(x => x.Type).Must(x => x.Equals("K") || x.Equals("D")).WithMessage("Err Message!");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-13
        • 2020-11-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多