I'm trying to make a validator which handles any combination of 2 props out of a total of 3. So if I have A, B, C then the validation should succeed if any A-B, B-C, C-A or A-B-C is valid.
I've written it so far something like
RuleFor(x=>x.A)
.Must(val=>!string.IsNullOrEmpty(val)
.When(x=> !(string.IsNullOrEmpty(x.B) && string.IsNullOrEmpty(x.C)));
RuleFor(x=>x.C)
.Must(val=>!string.IsNullOrEmpty(val)
.When(x=> !(string.IsNullOrEmpty(x.B) && string.IsNullOrEmpty(x.A)));
RuleFor(x=>x.B)
.Must(val=>!string.IsNullOrEmpty(val)
.When(x=> !(string.IsNullOrEmpty(x.A) && string.IsNullOrEmpty(x.C)));
When(x=> string.IsNullOrEmpty(x.A), ()=>{
/// validate A according to business
})
When(x=> string.IsNullOrEmpty(x.B), ()=>{
/// validate B according to business
})
When(x=> string.IsNullOrEmpty(x.C), ()=>{
/// validate C according to business
})
But this does not work and I cannot find a way to make the validator work
You can use the Must
method to create a custom validation rule that checks your custom rule inside:
RuleFor(x => x)
.Must(x => !string.IsNullOrEmpty(x.A) && !string.IsNullOrEmpty(x.B)
|| !string.IsNullOrEmpty(x.B) && !string.IsNullOrEmpty(x.C)
|| !string.IsNullOrEmpty(x.C) && !string.IsNullOrEmpty(x.A)
|| !string.IsNullOrEmpty(x.A) && !string.IsNullOrEmpty(x.B) && !string.IsNullOrEmpty(x.C))
.WithMessage("At least two of A, B, and C must be non-empty.");
Then you can add additional rules to validate each individual property:
When(x => string.IsNullOrEmpty(x.A), () => {
RuleFor(x => x.B)
.NotEmpty()
.WithMessage("B is required when A is empty.");
RuleFor(x => x.C)
.NotEmpty()
.WithMessage("C is required when A is empty.");
});
When(x => string.IsNullOrEmpty(x.B), () => {
RuleFor(x => x.A)
.NotEmpty()
.WithMessage("A is required when B is empty.");
RuleFor(x => x.C)
.NotEmpty()
.WithMessage("C is required when B is empty.");
});
When(x => string.IsNullOrEmpty(x.C), () => {
RuleFor(x => x.A)
.NotEmpty()
.WithMessage("A is required when C is empty.");
RuleFor(x => x.B)
.NotEmpty()
.WithMessage("B is required when C is empty.");
});