复杂的验证扩展

时间:2014-08-29 11:27:51

标签: c# validation generics fluentvalidation

在为Fluent验证规则构建器编写扩展时,我提出了进行更复杂验证的想法,然后将其与客户端验证联系起来。我已经成功创建了基于另一个属性验证一个属性的扩展,依此类推。我正在努力解决的问题是多个领域的验证:

https://fluentvalidation.codeplex.com/wikipage?title=Custom&referringTitle=Documentation

上的扩展方法
public static IRuleBuilderOptions<T, TProperty> Required<T, TProperty>(this IRuleBuilder<T, TProperty> ruleBuilder, Action<MyRuleBuilder<T>> configurator)
    {
        MyRuleBuilder<T> builder = new MyRuleBuilder<T>();

        configurator(builder);

        return ruleBuilder.SetValidator(new MyValidator<T>(builder));
    }

MyRuleBuilder类,允许流利地添加规则:

public class MyRuleBuilder<T>
{
    public Dictionary<string, object> Rules = new Dictionary<string,object>();

    public MyRuleBuilder<T> If(Expression<Func<T, object>> exp, object value)
    {
        Rules.Add(exp.GetMember().Name, value);

        return this;
    }
}

然后视图模型和视图模型验证器规则如下所示:

public class TestViewModel
{
    public bool DeviceReadAccess { get; set; }
    public string DeviceReadWriteAccess { get; set; }
    public int DeviceEncrypted { get ; set; }
}

RuleFor(x => x.HasAgreedToTerms)
    .Required(builder => builder
        .If(x => x.DeviceReadAccess, true)
        .If(x => x.DeviceReadWriteAccess, "yes")
        .If(x => x.DeviceEncrypted, 1 ));

问题:

以上工作正常,但我不喜欢的是&#34; If&#34;功能。它不会将值强制为选定的属性类型。例如:

RuleFor(x => x.HasAgreedToTerms)
    .Required(builder => builder
        .If(x => x.DeviceReadAccess, true) // I would like the value to be enforced to bool
        .If(x => x.DeviceReadWriteAccess, "yes") // I would like the value to be enforced to string

// Ideally something like 

// public MyRuleBuilder<T> If(Expression<Func<T, U>> exp, U value) but unfortunately U cannot be automatically inferred

这种架构是否可行,或者我应采取不同的方法?

感谢。

1 个答案:

答案 0 :(得分:0)

我认为你可以在方法中添加另一个通用参数U

public class MyRuleBuilder<T>
{
    public Dictionary<string, object> Rules = new Dictionary<string, object>();

    public MyRuleBuilder<T> If<U>(Expression<Func<T, U>> exp, U value)
    {
        Rules.Add(exp.GetMember().Name, value);

        return this;
    }
}