Middleware is a crucial component of ASP.NET Core, which is renowned for its excellent performance, modularity, and adaptability. In ASP.NET Core applications, middleware creates the request-response pipeline. Middleware is an essential topic for any.NET Core developer since every HTTP request and response passes through this pipeline.


What Is Middleware in ASP.NET Core?
Middleware is a software component that:

  • Handles HTTP requests and responses
  • Can inspect, modify, or short-circuit requests
  • Is executed sequentially in a pipeline

Each middleware component can:

  • Process the request
  • Call the next middleware
  • Process the response

Think of middleware as checkpoints that every request must pass through.

ASP.NET Core Request Pipeline
When a request hits an ASP.NET Core application:

  • It enters the middleware pipeline
  • Each middleware runs in the order it is registered
  • The response flows back in reverse order

Request → Middleware 1 → Middleware 2 → Middleware 3 → Controller
Response ← Middleware 1 ← Middleware 2 ← Middleware 3


The order of middleware registration is extremely important.

Common Built-in Middleware

ASP.NET Core provides several built-in middleware components:

MiddlewarePurpose
UseRouting Matches incoming requests to routes
UseAuthentication Authenticates users
UseAuthorization Authorizes users
UseEndpoints Executes matched endpoints
UseExceptionHandler Global exception handling
UseStaticFiles Serves static files

Example pipeline in Program.cs:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.UseExceptionHandler("/error");
app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.Run();

Types of Middleware
1. Inline Middleware
Defined directly using Use or Run.
app.Use(async (context, next) =>
{
    // Before next middleware
    await context.Response.WriteAsync("Before Middleware\n");

    await next();

    // After next middleware
    await context.Response.WriteAsync("After Middleware\n");
});

2. Terminal Middleware
Does not call the next middleware.
app.Run(async context =>
{
    await context.Response.WriteAsync("Request handled here.");
});

Once Run() is executed, the pipeline stops.

3. Custom Middleware

For reusable and clean code, create custom middleware.

Step 1: Create Middleware Class
public class RequestLoggingMiddleware
{
    private readonly RequestDelegate _next;

    public RequestLoggingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        Console.WriteLine($"Request: {context.Request.Method} {context.Request.Path}");
        await _next(context);
    }
}


Step 2: Register Middleware
app.UseMiddleware<RequestLoggingMiddleware>();

Short-Circuiting the Pipeline

Middleware can stop further execution:

app.Use(async (context, next) =>
{
    if (!context.User.Identity.IsAuthenticated)
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
        return;
    }

    await next();
});

This technique is commonly used in:

  • Authentication
  • Authorization
  • Rate limiting

Best Practices for Middleware

  • Register middleware in the correct order
  • Keep middleware lightweight
  • Use custom middleware for reusable logic
  • Avoid heavy business logic in middleware
  • Prefer exception-handling middleware at the top
  • Don’t perform long-running tasks
  • Don’t ignore async/await

Middleware vs Filters

MiddlewareFilters
Works on HTTP level Works on MVC level
Applies globally Applies to controllers/actions
Runs before routing Runs after routing

Use middleware for cross-cutting concerns like logging, security, and error handling.

Conclusion
Middleware is the backbone of ASP.NET Core. Understanding how it works empowers developers to:

  • Build secure applications
  • Improve performance
  • Implement clean cross-cutting concerns

Mastering middleware means mastering the ASP.NET Core request pipeline.