Reputation: 65
I need some clarification on how exactly the instance whos property is being validated, is passed down to each validator in a rule.
Let's assume the following:
RuleFor(x => x.MyProperty).SetValidator(new MyCustomValidator()).NotNull();
The MyCustomValidator will set a value on MyProperty if the value is NULL in some cases.
I would expect that the NotNull validation would pass.
However, it appears this is not the case.
When I split up the RuleFor into two seperate calls:
RuleFor(x => x.MyProperty).SetValidator(new MyCustomValidator());
RuleFor(x => x.MyProperty).NotNull();
it works as expected.
But of course, i'd like to avoid having multiple "RuleFor" statements for the same property
This makes me believe that at the start of the "RuleFor", the instance and/or property value being validated is cached/copied and then provided to each validator specified for that rule.
I've also created a fiddle demonstrating this behaviour here: https://dotnetfiddle.net/rDTrDU
Upvotes: 0
Views: 431
Reputation: 143078
The chained one will create one PropertyRule
with multiple components and when they are processed FluentValidation
caches property value and uses it for every component:
var accessor = new Lazy<TProperty>(() => PropertyFunc(context.InstanceToValidate), LazyThreadSafetyMode.None);
The not chained one creates multiple PropertyRule
s with one component so after the first rule is validated the MyObject
instance will be modified and property accessor will use the new value.
In your case I would try to use PreValidate
in MyObjectValidator
:
public class MyObjectValidator : AbstractValidator<MyObject>
{
protected override bool PreValidate(ValidationContext<MyObject> context, ValidationResult result)
{
var version = context.RootContextData["SourceVersion"] as Version;
if (version < new Version(2, 0, 0) && string.IsNullOrWhiteSpace(context.InstanceToValidate.MyProperty))
{
Console.WriteLine("\t[DEBUG]: Setting value to 'Hello world'");
context.InstanceToValidate.MyProperty = "Hello world";
}
return true;
}
....
}
Upvotes: 1