AbstractValidator<T> is the FluentValidation base class for defining validation rules in a separate validator class for each model. Its RuleFor() method targets a property, while chained methods such as NotEmpty(), Length(), and Must() describe that property's requirements. section 32.4.1 section 32.5
Currency converter validator
A validator can keep a binding model free of validation attributes while expressing its rules together: CurrencyConverterModelValidator : AbstractValidator<CurrencyConverterModel>. Its constructor can call RuleFor(x => x.CurrencyFrom).NotEmpty().Length(3).Must(...), then apply a custom error message with WithMessage(). section 32.4.1
Listing 32.11 A FluentValidation validator for the currency converter binding model
public class CurrencyConverterModelValidator #1
: AbstractValidator<CurrencyConverterModel> #1
{
private readonly string[] _allowedValues #2
= new []{ "GBP", "USD", "CAD", "EUR" }; #2
public CurrencyConverterModelValidator() #3
{
RuleFor(x => x.CurrencyFrom) #4
.NotEmpty() #5
.Length(3) #5
.Must(value => _allowedValues.Contains(value)) #6
.WithMessage("Not a valid currency code"); #6
RuleFor(x => x.CurrencyTo)
.NotEmpty()
.Length(3)
.Must(value => _allowedValues.Contains(value))
.WithMessage("Not a valid currency code");
RuleFor(x => x.Quantity)
.NotNull()
.InclusiveBetween(1, 1000); #7
}
}
Inspect the complete currency converter validator, including allowed currency codes, quantity limits, and chained property rules. section 32.4.1
Extend a validator as requirements become more specific:
- Use Must() for arbitrary predicates, including rules that compare two model properties. section 32.4.1
- Extract repeated rules into extension methods such as MustBeCurrencyCode(). section 32.4.1
- Inject services into the validator when validation depends on application data. section 32.4.1
