ASP.NET Core Middleware - Quick Reference

SkillAI & models

ASP.NET Core custom middleware, pipeline order, exception handling middleware, and request/response manipulation.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the ASP.NET Core Middleware - 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-middleware/SKILL.md and read by ahel’s review.

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: aspnet-core, topic: middleware for comprehensive documentation.

Pipeline Order

Request → Exception Handler → HSTS → HTTPS Redirect → Static Files
→ CORS → Authentication → Authorization → Custom Middleware → Endpoint
var app = builder.Build();

// 1. Exception handling (first to catch all)
app.UseExceptionHandler("/error");
app.UseHsts();

// 2. HTTPS and static files
app.UseHttpsRedirection();
app.UseStaticFiles();

// 3. Routing
app.UseRouting();

// 4. CORS (before auth)
app.UseCors();

// 5. Auth
app.UseAuthentication();
app.UseAuthorization();

// 6. Custom middleware
app.UseMiddleware<RequestLoggingMiddleware>();

// 7. Endpoints
app.MapControllers();

Custom Middleware (Convention-based)

public class RequestLoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<RequestLoggingMiddleware> _logger;

    public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var sw = Stopwatch.StartNew();

        _logger.LogInformation("Request {Method} {Path}", context.Request.Method, context.Request.Path);

        await _next(context);

        sw.Stop();
        _logger.LogInformation("Response {StatusCode} in {Elapsed}ms",
            context.Response.StatusCode, sw.ElapsedMilliseconds);
    }
}

// Register
app.UseMiddleware<RequestLoggingMiddleware>();

Exception Handling Middleware

public class ExceptionMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<ExceptionMiddleware> _logger;

    public ExceptionMiddleware(RequestDelegate next, ILogger<ExceptionMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (NotFoundException ex)
        {
            context.Response.StatusCode = StatusCodes.Status404NotFound;
            await context.Response.WriteAsJsonAsync(new { error = ex.Message });
        }
        catch (ValidationException ex)
        {
            context.Response.StatusCode = StatusCodes.Status400BadRequest;
            await context.Response.WriteAsJsonAsync(new { errors = ex.Errors });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Unhandled exception");
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            await context.Response.WriteAsJsonAsync(new { error = "An unexpected error occurred" });
        }
    }
}

Inline Middleware

// Simple Use
app.Use(async (context, next) =>
{
    context.Response.Headers.Append("X-Request-Id", Guid.NewGuid().ToString());
    await next(context);
});

// Terminal middleware (does not call next)
app.Map("/health", app => app.Run(async context =>
{
    await context.Response.WriteAsync("OK");
}));

Anti-Patterns

Anti-PatternWhy It's BadCorrect Approach
Wrong middleware orderAuth bypassed, CORS failsFollow documented order
Exception handler not firstMisses early errorsPlace at start of pipeline
Reading body without bufferingStream consumed onceEnable EnableBuffering()
Blocking calls in middlewareThread starvationUse async Task InvokeAsync

Quick Troubleshooting

IssueLikely CauseSolution
CORS not workingWrong orderPlace UseCors() before UseAuth
Middleware not executingRegistered after endpointsRegister before MapControllers()
Body empty in middlewareAlready read by bindingUse EnableBuffering()
Static files not servedWrong orderPlace UseStaticFiles() early

Signals

GitHub stars
33
Forks
6
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
aspnet-middleware
Source
github.com/claude-dev-suite/claude-dev-suite