Asynchronous Validation

In some situations, you may wish to define asynchronous rules, for example when working with an external API. By default, FluentValidation allows custom rules defined with MustAsync or CustomAsync to be run asynchronously, as well as defining asynchronous conditions with WhenAsync.

A simplistic solution that checks if a user ID is already in use using an external web API:

public class CustomerValidator : AbstractValidator<Customer> 
{
  SomeExternalWebApiClient _client;

  public CustomerValidator(SomeExternalWebApiClient client) 
  {
    _client = client;

    RuleFor(x => x.Id).MustAsync(async (id, cancellation) => 
    {
      bool exists = await _client.IdExists(id);
      return !exists;
    }).WithMessage("ID Must be unique");
  }
}

Invoking the validator is essentially the same, but you should now invoke it by calling ValidateAsync:

var validator = new CustomerValidator(new SomeExternalWebApiClient());
var result = await validator.ValidateAsync(customer);

Note

Calling ValidateAsync will run both synchronous and asynchronous rules.

Warning

If your validator contains asynchronous validators or asynchronous conditions, it’s important that you always call ValidateAsync on your validator and never Validate. If you call Validate, then an exception will be thrown.

You should not use asynchronous rules when using automatic validation with ASP.NET as ASP.NET’s validation pipeline is not asynchronous. If you use asynchronous rules with ASP.NET’s automatic validation, they will always be run synchronously (10.x and older) or throw an exception (11.x and newer).