Aspnet Middleware
title: ASP.NET Core Middleware — Complete Guide to Request Pipeline description: 'Learn ASP.NET Core middleware: pipeline architecture, built-in middleware, custom middleware, ordering, short-circuiting, and branching the pipeline with Map/Use/When.' date: 2026-06-28 lastmod: 2026-06-28 weight: 19 tags: [backend, aspnet]
ASP.NET Core middleware components form a pipeline that processes HTTP requests and responses, with each component choosing whether to pass to the next or short-circuit.
## What You'll Learn
By the end of this tutorial, you'll understand the request pipeline, use built-in middleware, create custom middleware, control pipeline ordering, short-circuit requests, and branch pipelines.
## Real-World Use
A request flows through: ExceptionHandler -> HttpsRedirection -> StaticFiles -> Routing -> Authentication -> Authorization -> Endpoint Middleware. Each piece handles one concern.
## Middleware Learning Path
```mermaid
flowchart LR
A[Routing] --> B[Middleware]
B --> C[DI]
C --> D[Config]
D --> E[EF Core]
B --> F{You Are Here}
style F fill:#f90,color:#fff
Built-in Middleware
var app = builder.Build();
// Order matters! Each middleware wraps the next.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage(); // 1. Error handling (outermost)
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection(); // 2. Redirect HTTP to HTTPS
app.UseStaticFiles(); // 3. Serve static files
app.UseRouting(); // 4. Route matching
app.UseCors(); // 5. Cross-origin
app.UseAuthentication(); // 6. Auth
app.UseAuthorization(); // 7. Authorization
app.MapControllers(); // 8. Endpoint execution (innermost)
Custom Middleware
// Class-based middleware
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
var start = DateTime.UtcNow;
_logger.LogInformation("Request: {Method} {Path}",
context.Request.Method, context.Request.Path);
await _next(context); // Call next middleware
var elapsed = (DateTime.UtcNow - start).TotalMilliseconds;
_logger.LogInformation("Response: {StatusCode} ({Elapsed}ms)",
context.Response.StatusCode, elapsed);
}
}
// Extension method for cleaner registration
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseRequestLogging(this IApplicationBuilder app)
=> app.UseMiddleware<RequestLoggingMiddleware>();
}
// Register in Program.cs
app.UseRequestLogging();
Middleware Branching
// Map: branch based on path prefix
app.Map("/api", apiApp =>
{
apiApp.UseAuthentication();
apiApp.UseAuthorization();
apiApp.Run(async context =>
{
await context.Response.WriteAsync("API endpoint");
});
});
// MapWhen: branch based on condition
app.MapWhen(ctx => ctx.Request.Query.ContainsKey("admin"), adminBranch =>
{
adminBranch.Use(async (context, next) =>
{
context.Response.Headers.Append("X-Admin-Mode", "true");
await next();
});
});
// Use: inline middleware
app.Use(async (context, next) =>
{
context.Items["RequestStartTime"] = DateTime.UtcNow;
await next();
});
Short-Circuiting
// Run: terminal middleware (never calls next)
app.Run(async context =>
{
await context.Response.WriteAsync("Short-circuited!");
});
// Conditional short-circuit
app.Use(async (context, next) =>
{
if (context.Request.Headers["X-Api-Key"] != "secret")
{
context.Response.StatusCode = 401;
return; // Don't call next
}
await next();
});
Common Mistakes
1. Wrong Middleware Order
Authentication before CORS blocks CORS preflight requests. StaticFiles before Routing serves files without route processing.
2. Not Calling await next()
Middleware that doesn't call await next() terminates the pipeline. Only do this intentionally (e.g., authentication failure).
3. Modifying Response After Sending
Once response headers are sent (first write), you can't modify status code or headers.
4. Heavy Operations in Middleware
Middleware runs on every request. Keep it lightweight. Put heavy operations (DB calls) in endpoint handlers.
5. Not Handling Exceptions
Without exception handling middleware, unhandled exceptions return 500 with no details.
Practice Questions
1. What is the middleware pipeline?
A series of components that process HTTP requests in order. Each component can process, pass, or short-circuit.
2. How do you create custom middleware?
Create a class with a RequestDelegate constructor parameter and an InvokeAsync(HttpContext) method.
3. What is the difference between Use, Map, and Run?
Use chains middleware. Map branches the pipeline by path prefix. Run is terminal middleware (ends the pipeline).
4. Why does middleware order matter?
Each middleware wraps the next. Exception handler must be outermost to catch exceptions from inner middleware.
5. Challenge: Create middleware that blocks requests from specific IP addresses.
public class IpBlockingMiddleware
{
private readonly RequestDelegate _next;
private readonly HashSet<string> _blockedIps;
public IpBlockingMiddleware(RequestDelegate next, IConfiguration config)
{
_next = next;
_blockedIps = config.GetSection("BlockedIPs").Get<HashSet<string>>() ?? new();
}
public async Task InvokeAsync(HttpContext context)
{
var ip = context.Connection.RemoteIpAddress?.ToString();
if (ip != null && _blockedIps.Contains(ip))
{
context.Response.StatusCode = 403;
return;
}
await _next(context);
}
}
FAQ
Mini Project: Request Timing Middleware
Create middleware that measures and logs request duration.
public class TimingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
public TimingMiddleware(RequestDelegate next, ILogger<TimingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
await _next(context);
stopwatch.Stop();
if (stopwatch.ElapsedMilliseconds > 1000)
_logger.LogWarning("Slow request: {Path} took {Time}ms",
context.Request.Path, stopwatch.ElapsedMilliseconds);
}
}
What's Next
ASP.NET Core Dependency Injection ASP.NET Core Configuration
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro