【问题标题】:fluentvalidation InclusiveBetween dynamically set rangefluentvalidation InclusiveBetween 动态设置范围
【发布时间】:2014-05-29 16:25:22
【问题描述】:

我正在使用 FluentValidation

我想使用以下方法进行范围验证:

包容性之间

  RuleFor(x => x.Height)
             .InclusiveBetween(x=> x.min, x.max).

我希望能够从模型中动态获取 'from' 和 'to' 值..而不是在验证器中进行硬编码

这可能吗?

谢谢

【问题讨论】:

  • 他们更新了框架。查看最新版 FluentValidation link

标签: model-view-controller fluentvalidation


【解决方案1】:

嗯,FluentValidation 中没有任何东西。

但是您可以编写自己的扩展方法(和验证器),类似这样的东西(快速,因此您必须将其做得更好,但您有这个想法)。

//the extension method
public static class ValidationExtensions
   {
        public static IRuleBuilder<T, TProperty> InclusiveBetween<T, TProperty>(this IRuleBuilder<T, TProperty> ruleBuilder, Expression<Func<T, TProperty>> fromExpression, Expression<Func<T, TProperty>> toExpression)
        {
           var fromFunc = leftExpression.Compile();
           var toFunc = rightExpression.Compile();
           return ruleBuilder.SetValidator(new InclusiveBetweenPropertyValidator(fromFunc.CoerceToNonGeneric(), fromExpression.GetMember(), toFunc.CoerceToNonGeneric(), toExpression.GetMember()));
        }
   }

然后是验证器类

public class InclusiveBetweenPropertyValidator : PropertyValidator, IBetweenValidator, IPropertyValidator
{
    public  Func<object, object> FromFunc { get; set; }
    public MemberInfo FromMemberInfo { get; set; }

    public Func<object, object> ToFunc { get; set; }
    public MemberInfo ToMemberInfo { get; set; }

    public IComparable From { get; private set; }
    public IComparable To { get; private set; }

    public InclusiveBetweenPropertyValidator(Func<object, object> fromFunc, MemberInfo fromMember, Func<object, object> toFunc, MemberInfo toMember)
        : base((() => Messages.inclusivebetween_error))
    {
        FromFunc = fromFunc;
        FromMemberInfo = fromMember;
        ToFunc = toFunc;
        ToMemberInfo = toMember;
    }


    protected override bool IsValid(PropertyValidatorContext context)
    {
        var comparable = (IComparable)context.PropertyValue;
        From = (IComparable)this.FromFunc(context.Instance);
        To = (IComparable)this.ToFunc(context.Instance);

        if (comparable == null || FluentValidation.Internal.Comparer.GetComparisonResult(comparable, From) >= 0 && FluentValidation.Internal.Comparer.GetComparisonResult(comparable, To) <= 0)
            return true;
        context.MessageFormatter.AppendArgument("From", string.Format("{0} ({1})", FromMemberInfo.Name, From)).AppendArgument("To", string.Format("{0} ({1})",ToMemberInfo.Name, To)).AppendArgument("Value", context.PropertyValue);
        return false;
    }
}

用法:

RuleFor(x => x.Height)
             .InclusiveBetween(x=> x.min, x.max)

【讨论】:

  • 这会让您进行自动客户端验证吗?
  • @raklos 不知道。很大的疑问,就像在 FluentValidation 文档中一样,它声明客户端验证不支持自定义验证器。但你可以测试...
【解决方案2】:

如果您不想编写扩展,可以使用 Predicate Validator 的额外重载 - 它也接受父对象的实例 - 如下所示:

RuleFor(x => x.Height)
    .Must((model, height) => height >= model.Min && height <= model.Max);

【讨论】:

    【解决方案3】:

    这与 Raphaël 的回答类似,但更多的是逐案使用,而不是一般使用扩展。

    RuleFor(x =&gt; x).Must(HeightValidation);

    private static bool HeightValidation(Model m)
    {
        return m.Height >= m.min && m.Height <= m.max;
    }
    

    【讨论】:

      【解决方案4】:

      让我们想象你的模型如下:

      public class YourModel
          {
              public int Height { get; set; }
              public int Min { get; set; }
              public int Max { get; set; }
          }
      

      那么验证将如下:

      public class YourModelValidation : AbstractValidator<YourModel>
          {
              public YourModelValidation(int min,int max)
              {
                  RuleFor(x => x.Height).InclusiveBetween(min, max);
              }
          }
      

      那么验证用法是:

      var validation = new YourModelValidation(model.Min,model.Max).Validate(model);
      

      如您所见,动态参数在验证的构造函数中传递。

      您可以将模型或 dto 作为构造函数参数传递

      【讨论】:

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