check another rule with fluentvalidation

1.3k views Asked by At

I have the following code to validate an entity:

   public class AffiliateValidator : AbstractValidator<Affiliate>
   {
    public AffiliateValidator ()
    {
        RuleFor(x => x.IBAN).SetValidator(new ValidIBAN()).Unless( x => String.IsNullOrWhiteSpace(x.IBAN));
     }
    }

And ValidIBAN() Code:

public class ValidIBAN  : PropertyValidator
{
    public ValidIBAN()
        :base("IBAN \"{PropertyValue}\" not valid.")
    {

    }

    protected override bool IsValid(PropertyValidatorContext context)
    {
        var iban = context.PropertyValue as string;
        IBAN.IBANResult result = IBAN.CheckIban(iban, false);
        return result.Validation == (IBAN.ValidationResult.IsValid);
    }

}

}

So,CheckIBAN method of IBAN class does the dirty job.

Now, what I need to to is apply the following rule for another property: If DirectDebit (bool) is true, then IBAN can't be empty and also it must be valid.

I can do this:

RuleFor(x => x.DirectDebit).Equal(false).When(a => string.IsNullOrEmpty(a.IBAN)).WithMessage("TheMessage.");

But how can I Invoke another rule, IBAN's rule in this case, in order to check if is or not valid?

1

There are 1 answers

0
Txaran On BEST ANSWER

Often the problems are simpler than they seem. This is the solution I adopt to aply the rule for DirectDebit field.

    RuleFor(x => x.DirectDebit).Must(HaveValidAccounts).When(x => x.DirectDebit)
            .WithMessage("TheMessage");

and change the rule for IBAN also:

 RuleFor(x => x.IBAN).Must(IsValidIBAN)
                            .Unless(x => String.IsNullOrWhiteSpace(x.IBAN))
                            .WithMessage("The IBAN \"{PropertyValue}\" is not valid.");

...and then:

   private bool HaveValidAccounts(ViewModel instance,   bool DirectDebit)
    {
        if (!DirectDebit)
        { return true; }

        bool CCCResult = IsValidCCC(instance.CCC);
        bool IBANResult = IsValidIBAN(instance.IBAN);

        return CCCResult || IBANResult;
    }

     private bool IsValidIBAN(string iban)
    {
        return CommonInfrastructure.Finantial.IBAN.CheckIban(iban, false).Validation == IBAN.ValidationResult.IsValid;
    }

the trick is use instance parameter of Must() to do whetever I want.