ASP.NET Minimal API - Quick Reference
SkillAI & modelsASP.NET Core Minimal API endpoints, route groups, filters, and typed results. Covers modern .NET 8+ endpoint patterns.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the ASP.NET Minimal API - Quick Reference skill
What this skill tells your AI
The instructions your AI receives, as published by claude-dev-suite/claude-dev-suite in skills/backend-frameworks/aspnet-minimal-api/SKILL.md and read by ahel’s review.
Deep Knowledge: Use
mcp__documentation__fetch_docswith technology:aspnet-core, topic:minimal-apifor comprehensive documentation.
Basic Endpoints
var app = WebApplication.Create(args);
app.MapGet("/api/users", async (IUserService service) =>
Results.Ok(await service.GetAllAsync()));
app.MapGet("/api/users/{id:int}", async (int id, IUserService service) =>
await service.GetByIdAsync(id) is { } user
? Results.Ok(user)
: Results.NotFound());
app.MapPost("/api/users", async (CreateUserRequest request, IUserService service) =>
{
var user = await service.CreateAsync(request);
return Results.Created($"/api/users/{user.Id}", user);
});
app.MapPut("/api/users/{id:int}", async (int id, UpdateUserRequest request, IUserService service) =>
await service.UpdateAsync(id, request) ? Results.NoContent() : Results.NotFound());
app.MapDelete("/api/users/{id:int}", async (int id, IUserService service) =>
{
await service.DeleteAsync(id);
return Results.NoContent();
});
app.Run();
Route Groups
var users = app.MapGroup("/api/users")
.WithTags("Users")
.RequireAuthorization();
users.MapGet("/", GetAll);
users.MapGet("/{id:int}", GetById);
users.MapPost("/", Create);
// Nested groups
var admin = app.MapGroup("/api/admin")
.RequireAuthorization("AdminOnly");
admin.MapGroup("/users").MapGet("/", GetAllUsers);
Endpoint Filters
// Validation filter
public class ValidationFilter<T> : IEndpointFilter where T : class
{
public async ValueTask<object?> InvokeAsync(
EndpointFilterInvocationContext context,
EndpointFilterDelegate next)
{
var argument = context.Arguments.OfType<T>().FirstOrDefault();
if (argument is null)
return Results.BadRequest("Invalid request body");
var validator = context.HttpContext.RequestServices.GetService<IValidator<T>>();
if (validator is not null)
{
var result = await validator.ValidateAsync(argument);
if (!result.IsValid)
return Results.ValidationProblem(result.ToDictionary());
}
return await next(context);
}
}
// Apply filter
users.MapPost("/", Create).AddEndpointFilter<ValidationFilter<CreateUserRequest>>();
TypedResults (.NET 7+)
app.MapGet("/api/users/{id:int}", async Task<Results<Ok<UserResponse>, NotFound>> (int id, IUserService service) =>
await service.GetByIdAsync(id) is { } user
? TypedResults.Ok(user)
: TypedResults.NotFound());
Anti-Patterns
| Anti-Pattern | Why It's Bad | Correct Approach |
|---|---|---|
| All endpoints in Program.cs | Hard to maintain | Use route groups and extension methods |
| No validation | Accepts bad input | Use endpoint filters |
| Inline business logic | Not testable | Inject services |
| Not using TypedResults | No OpenAPI metadata | Use TypedResults for typed responses |
Quick Troubleshooting
| Issue | Likely Cause | Solution |
|---|---|---|
| Parameter not bound | Wrong type or name | Use explicit [FromRoute] / [FromQuery] |
| Filter not executing | Not registered | Add with AddEndpointFilter<T>() |
| OpenAPI missing types | Using Results.Ok() | Use TypedResults.Ok() |
| Route conflicts | Ambiguous routes | Add route constraints like {id:int} |
Signals
- GitHub stars
- 33
- Forks
- 6
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
aspnet-minimal-api- Source
- github.com/claude-dev-suite/claude-dev-suite