public class ProspectValidator : AbstractValidator<Prospect>
{
public ProspectValidator()
{
RuleFor(p => p.CompetitorProducts)
.NotNull()
.When(p => !p.ExistingCustomer);
RuleFor(p => p.CompetitorProducts.Count)
.GreaterThan(0)
.When(p => p.CompetitorProducts != null && !p.ExistingCustomer);
}
}
This validator checks that if ExistingCustomer
is false then CompetitorProducts
is not null and has at least one element.
It works but is it possible to write this as one rule?
You have two options for doing this in a single command, but they are both a bit tricky as you need to validate an inner property while validating that the encompassing class is not null. They both revolve around the Cascade
property (see "Setting the Cascade Mode") to stop the validation on the first error.
First, you can use Must
to do the validation. You will need to specify a WithMessage
as I've done to avoid getting a generic "The specified condition was not met for 'Competitor Products'." error. You may also want to override the WithErrorCode
as it defaults to Predicate
. Note that this will only show on the second validation error; the first error will still correctly return the message that the property must not be null.
RuleFor(p => p.CompetitorProducts)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotNull()
.Must(p => p.Count > 0)
.WithMessage("{PropertyName} must be greater than '0'")
.When(p => !p.ExistingCustomer);
Second, you can provide a validator for the CompetitorProducts
class as a whole. This will allow you to have FluentValidation manage the error message and code. This will work well if you have other validations that must occur on the class, but might be overkill if you just need to validate the single property.
public class ProspectValidator: AbstractValidator<Prospect>
{
public CurrentUserValidator()
{
RuleFor(p => p.CompetitorProducts)
.Cascade(CascadeMode.StopOnFirstFailure)
.NotNull()
.SetValidator(new CompetitorProductsValidator())
.When(p => !p.ExistingCustomer);
}
}
public class CompetitorProductsValidator : AbstractValidator<Prospect.CompetitorProducts>
{
public CompetitorProductsValidator()
{
RuleFor(p => p.Count)
.GreaterThan(0);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With