The New Built-in Validation in .NET 10 Minimal APIs — Goodbye, FluentValidation Boilerplate?
.NET 10 finally wires data annotations into Minimal API endpoints with a single AddValidation call. FluentValidation still has a job — just a smaller one.
The single biggest "still rough" edge of Minimal APIs pre-.NET 10 was validation. You either wrote it manually inside each handler, added a custom endpoint filter, or installed FluentValidation. .NET 10 fixes this at the framework level with AddValidation().
Before (manual / custom filter):
app.MapPost("/orders", (Order o) =>
{
if (string.IsNullOrWhiteSpace(o.Sku)) return Results.BadRequest("Sku required");
if (o.Qty <= 0 || o.Qty > 999) return Results.BadRequest("Qty out of range");
return Results.Ok(o);
});
After:
builder.Services.AddValidation();
app.MapPost("/orders", (Order o) => Results.Ok(o));
public record Order([Required, StringLength(100)] string Sku, [Range(1, 999)] int Qty);
Bad input returns RFC 7807 ProblemDetails for free:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": { "Sku": [ "The Sku field is required." ] }
}
It also wires IValidatableObject.Validate(ValidationContext) if you implement it — for cross-field rules that don't fit on attributes.
The question becomes: do you still need FluentValidation?
For most CRUD endpoints, no. The built-in path covers required, range, regex, length, custom attribute-based rules, and conditional cross-field via IValidatableObject. That's 80% of what FluentValidation was doing.
You still want FluentValidation when:
- Your validation rules depend on external state (DB lookup, service call).
IValidatableObjectis sync and synchronous-data-only. - You have very complex rule trees that benefit from FluentValidation's
RuleSet, dependent rules, and chained conditions. - You're already invested in it across a large codebase. Don't migrate for migration's sake.
When you can drop it:
- New services where the rules fit on annotations.
- Services where validation is genuinely simple and you only added FluentValidation for "completeness."
The migration approach: add AddValidation() alongside FluentValidation in an existing service, move new endpoints to attribute-based validation, leave the existing ones until you're touching them anyway. Don't do a big-bang migration for cosmetic reasons.
Net effect: the gap that made me reach for Controllers on a "real" project has closed. Minimal APIs in .NET 10 are now genuinely a complete story for serious endpoints, not just toy ones.