Ivan-Mark Debono
Ivan-Mark Debono

Reputation: 16330

Combine multiple rules into one rule

I have the following rule:

RuleFor(x => x.FromNumber).NotEmpty().GreaterThan(0).When(x => x.NumbersRequired).WithState(x => MyErrorEnum.FromNumberRequired);

The property FromNumber is of type int?. The problem with the above is that CustomState is only set for GreaterThan. If the value is null or 0, CustomState is null.

If I change the above to the following the rule still works as expected:

RuleFor(x => x.FromNumber ?? 0).GreaterThan(0).When(x => x.NumbersRequired).WithState(x => MyErrorEnum.FromNumberRequired);

But is there a better way to combine both rules into one rule instead of using the null conditional operator?

Upvotes: 4

Views: 1553

Answers (1)

Electrionics
Electrionics

Reputation: 6782

The reasons to use several predefined validation rules instead of one custom, are:

  1. have properly generated client-side validation attributes in MVC
  2. have different error messages (by using default error messages, or WithMessage method)

1-st reason isn't your case, because you use When condition — it cancels any client-side attributes generation for affected rules.

2-nd not critical for your case, because you can combine error messages into one, if you need to do this.

So you can combine your rules into single predicate rule:

RuleFor(x => x.FromNumber)
    .Must(x => x != null && x > 0)
    .When(x => x.NumbersRequired)
    .WithState(x => MyErrorEnum.FromNumberRequired);

P.S. Syntax like this:

RuleFor(x => x.FromNumber ?? 0)

not only changes validated value, but also can change referrenced property name in unpredictable way when constructing dictionary of errors. Use property chain expression only in RuleFor / RuleForEach methods. If you prefer to use complex expressions like this — do not forget to specify actual property name in .WithName() method.

Upvotes: 1

Related Questions