Minimal APIs have always made the happy path look good.

The unhappy path took more work. You could decorate a request model with Data Annotations, but nothing automatically validated it. Most of us wrote an endpoint filter, pulled in another package, or checked every property by hand.

ASP.NET Core 10 adds validation directly to Minimal APIs.

Try It

Create a .NET 10 empty web app:

Terminal window
dotnet new web -n MinimalValidationDemo -f net10.0
cd MinimalValidationDemo

Replace Program.cs with this:

using System.ComponentModel.DataAnnotations;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddValidation();
var app = builder.Build();
app.MapPost("/products", (CreateProduct request) =>
{
var product = new Product(
Id: Random.Shared.Next(1, 10_000),
request.Name,
request.Quantity);
return TypedResults.Created($"/products/{product.Id}", product);
});
app.Run();
public sealed record CreateProduct(
[Required, StringLength(100, MinimumLength = 3)]
string Name,
[Range(1, 1_000)]
int Quantity);
public sealed record Product(int Id, string Name, int Quantity);

Run it:

Terminal window
dotnet run

Send an invalid request:

Terminal window
curl -i -X POST http://localhost:5000/products -H "Content-Type: application/json" -d "{\"name\":\"\",\"quantity\":0}"

Use the HTTP URL shown by dotnet run if your port is different. ASP.NET Core returns 400 Bad Request before your handler runs.

Send a valid request:

Terminal window
curl -i -X POST http://localhost:5000/products -H "Content-Type: application/json" -d "{\"name\":\"Mechanical Keyboard\",\"quantity\":4}"

Validation Isn’t Limited to Request Bodies

The generated validation filter can validate values from the request body, query string, and headers:

app.MapGet("/inventory", (
[Range(1, 100)] int pageSize,
[Required] string warehouse) =>
{
return TypedResults.Ok(new { pageSize, warehouse });
});

The Multi-Assembly Gotcha

AddValidation() uses a source generator. It discovers validatable endpoint types in the assembly where you call it.

If your endpoints live in a separate class library, call AddValidation() from that assembly. Otherwise your attributes can look correct while the generated validation metadata never sees them.

You can disable validation for a specific endpoint with .DisableValidation(), but use that on purpose. Turning it off because a model is inconvenient usually means the model needs another look.

Key Takeaway

ASP.NET Core 10 can validate Minimal API inputs before your handler runs. Add AddValidation(), decorate the model you already have, and let the framework produce the 400 response.