Spencer Stream
Spencer Stream

Reputation: 616

Conditional Validation with Multiple Conditions

I am familiar with simple conditional validation in FluentValidation using When, Unless, and Otherwise. This works well for validating on a single condition.

I would like to validate based off of an if-elseif-else statement, but I cannot determine how to do so.

I want to achieve

if (product == Product.A)
{
    // Validation for Product A
}
else if (product == Product.B)
{
    // Validation for Product B
}
else
{
    // Fail validation for other products
}

What I currently have works if I only want to check for a single product, e.g. Product A

When(
    order => order.Product == Product.A,
    () =>
    {
    RuleFor(order => order.State)
        .Must(
            state => state == State.HI
            || state == State.AK)
        .WithMessage("Product A only valid in Hawaii and Alaska.");
    }).Otherwise(
    () =>
    {
        RuleFor(order => order.Product)
            .Equal(Product.A)
            .WithMessage("Order only available with Product A.");
    });

What I'd like is to combine multiple When methods for Products A and B and have an otherwise that fails with the message "Order is only available with Products A or B".

Upvotes: 2

Views: 2041

Answers (1)

Jevon Kendon
Jevon Kendon

Reputation: 686

I've tackled similar problems by splitting up the rules, and putting guards on them.

Following your if-else psuedo code:

RuleFor(order => order.State)
    .Must(state => state == State.HI || state == State.AK)
    .WithMessage("Product A only valid in Hawaii and Alaska."))
    .When(order => order.Product == Product.A);

RuleFor(order => order.State)
    .Must(state => state == State.DC || state == State.CA)
    .WithMessage("Product B only valid in Washington and California."))
    .When(order => order.Product == Product.B);

// the not Product.A or Product.B case (I'm not sure what you want here) - but this 
// demonstrates a kind of "meta" rule to be applied to the whole order
RuleFor(order => order)
    .Must(order => order.Product == Product.A || order.Product == Product.B)
    .WithName("Order")
    .WithMessage(order => $"Order must be either {Product.A} or {Product.B}");

Upvotes: 1

Related Questions