Previously I’ve presented some introduction to Fluent Validation. In this post, I’m going to cover some configuration possibilities. Such as arranging validation processing to receive different results.

Cascade mode

At first, let’s manage validation execution. Cascade mode allows to setup how chained validators are executed. For example, there is a rule with two validators NotEmpty and GreaterThan:

RuleFor(e => e.Number)
  .NotEmpty()
  .GreaterThan(10);

When using that rule, it checks both of the validators no matter if the first validator fails or not. We can change cascade mode to stop at first failure.

RuleFor(e => e.Number)
  .Cascade(CascadeMode.StopOnFirstFailure)
  .NotEmpty()
  .GreaterThan(10);

There are two cascade modes to list:

  • Continue - set by default, all validators are checked
  • StopOnFirstFailure - stops checking after the first failure

You can also specify cascade mode for the whole validator adding this line in the constructor:

CascadeMode = CascadeMode.StopOnFirstFailure;

Also it’s possible to change it globally:

ValidatorOptions.CascadeMode = CascadeMode.StopOnFirstFailure;

However, you need to remember that it only works for validators in one rule chain. On the other hand, if you want RuleFor to be conditional on another one, you need to use Dependent Rules.

Result options

Fluent validation allows customizing errors. For example ErrorCode of NonEmpty validator equals NotEmptyValidator. You can change it if you want to have more descriptive value.

RuleFor(e => e.Text)
  .NotEmpty()
  .WithErrorCode("TextRequired");

In addition, you can also override the error message. It works similar to changing error code.

RuleFor(e => e.Text)
  .NotEmpty()
  .WithMessage("You need to set value for Text");

All messages can have specific placeholders based on validator type. All of them are replaced by the appropriate value.

RuleFor(e => e.Text)
  .NotEmpty()
  .WithMessage("You need to set value for {PropertyName}");

Placeholders

  • At first, there are available placeholders for all validators:
    • {PropertyName}
    • {PropertyValue}
  • Next, when comparing values such as Equals, GreaterThan, etc.:
    • {ComparisonValue} – value with which we comparing property value
  • Similarly, length validators provides:
    • {MinLength}
    • {MaxLength}

In addition, full list of placeholders for specific validators you can find here.

Localization

All default messages have translations for many different languages. When you create a custom message you can use localized error messages. It requires resource type and value:

RuleFor(e => e.Text)
  .NotEmpty()
  .WithLocalizedMessage(typeof(MyMessages), "TextRequired");

Moreover, by default Fluent Validation uses the thread’s CurrentUICulture for localization. You can disable it and use always English messages:

ValidatorOptions.LanguageManager.Enabled = false;

However, you can also set your own localization, for example:

ValidatorOptions.LanguageManager.Culture = new CultureInfo("pl");

In the next post, I’ll show more complex validation. For example custom validators and dependent rules.