I want to make a conditional to execute the CPF rule only when dealing with a CPF with length == 11
, and execute the CNPJ rule only when dealing with a CNPJ with length > 11
.
However, I realized that even with When
, both methods are executed (MustBeAValidCPF
and MustBeAValidCNPJ
).
Is there a way to run it only when the When
returns true
?
RuleFor(x => x.Code)
.NotEmpty()
.WithMessage(m => "Code cannot be empty")
.MinimumLength(11)
.WithMessage(m => "Code minimum length is 11")
.MustBeAValidCPF()
.When(x => x.Code?.Length == 11)
.MustBeAValidCNPJ()
.When(x => x.Code?.Length > 11);
Methods (extensions):
public static IRuleBuilderOptions<T, string> MustBeAValidCPF<T>(this IRuleBuilder<T, string> ruleBuilder)
{
return ruleBuilder.IsValidCPF().WithMessage("CPF is invalid");
}
public static IRuleBuilderOptions<T, string> MustBeAValidCNPJ<T>(this IRuleBuilder<T, string> ruleBuilder)
{
return ruleBuilder.IsValidCNPJ().WithMessage("CNPJ is invalid");
}
CodePudding user response:
As described in the documentation, the When
method has an optional parameter to modify this behavior.
By default:
If the second parameter is not specified, then it defaults to
ApplyConditionTo.AllValidators
, meaning that the condition will apply to all preceding validators in the same chain.
To achieve what you want, pass ApplyConditionTo.CurrentValidator
as the second parameter of both calls to When
:
RuleFor(x => x.Code)
.NotEmpty()
.WithMessage(m => "Code cannot be empty")
.MinimumLength(11)
.WithMessage(m => "Code minimum length is 11")
.MustBeAValidCPF()
.When(x => x.Code?.Length == 11, ApplyConditionTo.CurrentValidator)
.MustBeAValidCNPJ()
.When(x => x.Code?.Length > 11, ApplyConditionTo.CurrentValidator);