Endpoint filters arrived as a stable, first-class feature in .NET 10 and give Minimal API developers the same interception model previously limited to controller actions. They execute before and after the handler, receive the full invocation context, and can short-circuit or modify results without adding middleware or separate filter attributes.

The practical benefit is reduced boilerplate. Instead of repeating validation or logging logic across dozens of lambda endpoints, you register a single filter class and apply it once per route or globally. The API surface is intentionally small, making the feature easy to adopt on existing codebases.

#Basic Filter Implementation

Create a filter by implementing IEndpointFilter. The InvokeAsync method receives the context and a next delegate that represents the remaining pipeline.

csharp
public class ValidationFilter : IEndpointFilter
{
    public async ValueTask<object?> InvokeAsync(
        EndpointFilterInvocationContext context,
        EndpointFilterDelegate next)
    {
        var dto = context.GetArgument<MyDto>(0);
        if (!MiniValidator.TryValidate(dto, out var errors))
            return Results.ValidationProblem(errors);

        return await next(context);
    }
}

#Applying Filters to Endpoints

Attach the filter at registration time. Filters can be scoped to a single route or added to a route group for reuse across multiple endpoints.

csharp
var todos = app.MapGroup("/todos").AddEndpointFilter<ValidationFilter>();

todos.MapPost("/", async (MyDto dto, TodoDb db) =>
{
    db.Todos.Add(new Todo { Title = dto.Title });
    await db.SaveChangesAsync();
    return Results.Created($"/todos/{dto.Id}", dto);
});

#Common Use Cases

  • Input validation before the handler runs
  • Standardized error logging and correlation IDs
  • Result transformation such as wrapping responses in a consistent envelope
  • Authorization checks that short-circuit with 403 responses

#Performance Considerations

Filters are allocated once per request and execute on the same thread as the handler. Avoid blocking calls inside InvokeAsync; use async delegates and keep allocations low by reusing any state the filter needs across requests.

When a filter short-circuits, the remaining pipeline including the handler is never invoked, which can measurably reduce CPU time on invalid requests.

Add endpoint filters to new Minimal API projects and to any high-traffic routes that currently duplicate cross-cutting code. The pattern keeps route handlers focused on business logic while still providing the interception points required for production applications.