Comprehensive validation extension
When writing extensions for Builder Fluent Validation, I came up with the idea of doing a more complex validation and then plugging it in with client validation. I have successfully created extensions that check one property against another and so on. What I am struggling with is multi-field validation:
Extension method as at 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 class that allows you to freely add rules:
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;
}
}
Then the rules for validating the view model and model view are as follows:
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 ));
Problem:
This works great, but I don't like the "If" function. it does not apply the value of the selected property type. Example:
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
Is this possible with this architecture or should I use a different approach?
Thank.
source to share
I think you can add one more general parameter to this method 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;
}
}
source to share