使用单个规则进行多属性检查

时间:2018-07-26 17:18:40

标签: c# fluentvalidation

如何通过扩展方法等来使内容简洁?还可以将InlineValidator合并到MainPropertyValidator类中吗?

public class PropertyDTOValidator : AbstractValidator<PropertyDTO>
{
    public PropertyDTOValidator()
    {

        RuleFor(p => p).SetValidator(new InlineValidator<PropertyDTO>
        {
            validator =>
            {
                return validator.RuleFor(p => p.MainProperty)
                    .SetValidator(new MainPropertyValidator());
            }
        }).When(p =>
        {
            var checkMainProperty = p.MainProperty.Id != -1;
            if (!checkMainProperty)
            {
                // Some actions...
            }

            return checkMainProperty;
        });
    }
    class MainPropertyValidator : AbstractValidator<PropertyDTO>
    {
        public MainPropertyValidator()
        {
            RuleFor(p => p.Id).Must(id =>
            {
                return id >= 1;
            }).WithMessage("MainProperty Id value is not valid...");

        }
    }
}

修改 我有以下扩展名,但我想将我的验证器合并为一个类,如InlineValidator。我检查了InlineValidator的代码,但无法合并InlineValidator和MainPropertyValidator。

public static class Extensions
{
    public static IRuleBuilderOptions<T, TProperty1> SetValidator<T, TProperty1, TProperty2>(this IRuleBuilderInitial<T, TProperty1> ruleBuilder,
        Expression<Func<T, TProperty2>> exp, IValidator<TProperty2> validator)
    {
        return ruleBuilder.SetValidator(new InlineValidator<T>
        {
            v => v.RuleFor(exp).SetValidator(validator)
        } as IValidator<TProperty1>);
    }
}

RuleFor(p => p).SetValidator(p => p.MainProperty, new MainPropertyValidator()).When(p =>{});

1 个答案:

答案 0 :(得分:0)

或者,可以使用以下扩展名;

public static class Extensions
{
    public static IRuleBuilderInitial<T, TProperty> When<T, TProperty>(this IRuleBuilderInitial<T, TProperty> rule, Func<T, bool> predicate, ApplyConditionTo applyConditionTo = ApplyConditionTo.AllValidators)
    {
        return rule.Configure(config =>
        {
            PropertyRule propertyRule = config;
            int num = (int)applyConditionTo;
            propertyRule.ApplyCondition(ctx => predicate((T)ctx.InstanceToValidate), (ApplyConditionTo)num);
        });
    }

    public static IRuleBuilderInitial<T, TProperty> Custom<T, TProperty, TProperty2>(this IRuleBuilder<T, TProperty> ruleBuilder, Expression<Func<TProperty, TProperty2>> expression, AbstractValidator<TProperty2> validator)
    {
        var propChain = PropertyChain.FromExpression(expression);
        var propName = propChain.ToString();
        var prop = expression.Compile();

        Func<string, string, string> joinStr = (s1, s2) => string.Join(".", new[] { s1, s2 }.Where(s => !string.IsNullOrEmpty(s)));
        return ruleBuilder.Custom((p, context) =>
        {
            var val = prop(p);
            var validationResult = validator.Validate(val);
            propName = joinStr(context.PropertyName, propName);

            foreach (var failure in validationResult.Errors)
            {
                failure.PropertyName = joinStr(propName, failure.PropertyName);
                context.AddFailure(failure);
            }
        });
    }
}

RuleFor(p => p).Custom(p => p.MainProperty, new MainPropertyValidator()).When(p =>
  {
      var checkMainProperty = p.MainProperty.Id != -1;
      if (!checkMainProperty)
      {
          // Some actions...
      }

      return checkMainProperty;
  });
相关问题