How did I do?*

FluentValidation exception after NotNull check

If you are validating a reference type which can be null, along with its properties, you may encounter a situation where the parent object being null causes FluentValidation to throw a NullReferenceException when validating the properties on that object.

Take the following rule in a custom Validator class:

RuleFor(request => request.ZipFile)
    .MustBeValidZipFile();

which uses the following extension method:

public static IRuleBuilderOptions<T, IFormFile> MustBeValidZipFile<T>(
    this IRuleBuilder<T, IFormFile> ruleBuilder)
{
    return ruleBuilder
        .NotNull()
            .WithMessage(ValidationMessages.FileIsNull)
        .Must(file => file.FileName.Length < MaxFilenameSize)
            .WithMessage(ValidationMessages.FilenameTooLong)
        .Must(file => file.Length > 0)
            .WithMessage(ValidationMessages.FileSizeMustNotBeZero)
        .Must(file => file.FileName.ToLower().EndsWith(".zip"))
            .WithMessage(ValidationMessages.ZipFilenameMustEndDotZip);
}

Even though the IFormFile is null, subsequent checks on its properties will continue to be performed, therefore, attempting to check the FileName property on that object will result in a NullReferenceException.

This can be avoided by using the Cascade method to stop execution on the first error.

RuleFor(request => request.ZipFile)
    .Cascade(CascadeMode.Stop)
    .MustBeValidZipFile();

This is covered in the FluentValidation documentation, but is tucked away under "other features" and not immediately obvious.