DataAnnotations Validation Middleware

::: tip There is also an HTTP specific middleware for WolverineFx.Http that uses the ProblemDetails specification. See DataAnnotations Validation Middleware for HTTP for more information. :::

::: warning While it is possible to access the IoC Services via ValidationContext, we recommend instead using a more explicit Validate or ValidateAsync() method directly in your message handler class for the data input. :::

For simple input validation of your messages, the Data Annotation Attributes are a good choice. The WolverineFx.DataAnnotationsValidation nuget package will add support for the built-in and custom attributes via middleware that will stop invalid messages from reaching the message handlers.

To get started, add the nuget package and configure your Wolverine Application:

using var host = await Host.CreateDefaultBuilder()
    .UseWolverine(opts =>
    {
        // Apply the validation middleware
        opts.UseDataAnnotationsValidation();
    }).StartAsync();

snippet source | anchor

Now you can decorate your messages with the built-in or custom ValidationAttributes:

public record CreateCustomer(
    // you can use the attributes on a record, but you need to
    // add the `property` modifier to the attribute
    [property: Required] string FirstName,
    [property: MinLength(5)] string LastName,
    [property: PostalCodeValidator] string PostalCode
) : IValidatableObject
{
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // you can implement `IValidatableObject` for custom
        // validation logic
        yield break;
    }
};
 
public class PostalCodeValidatorAttribute : ValidationAttribute
{
    public override bool IsValid(object? value)
    {
        // custom attributes are supported
        return true;
    }
}
 
public static class CreateCustomerHandler
{
    public static void Handle(CreateCustomer customer)
    {
        // do whatever you'd do here, but this won't be called
        // at all if the DataAnnotations Validation rules fail
    }
}

snippet source | anchor

In the case above, the Validation check will happen at runtime before the call to the handler methods. If the validation fails, the middleware will throw a ValidationException and stop all processing.

Some notes about the middleware:

  • The middleware is applied to all message handler types as there is no easy way of knowing if a message has some sort of validation attribute defined.
  • The registration also adds an error handling policy to discard messages when a ValidationException is thrown

Customizing the Validation Failure Behavior

Out of the box, the Fluent Validation middleware will throw a DataAnnotationsValidation.ValidationException with all the validation failures if the validation fails. To customize that behavior, you can plug in a custom implementation of the IFailureAction<T> interface. This behaves exactly the same as the Fluent Validation Customisation.



url: /guide/durability/efcore/migrations.md