🧠 Introduction
ASP.NET Core is known for its modular pipeline, where middleware components play a critical role in handling HTTP requests and responses. Middleware can perform a variety of tasks such as request logging, authentication, routing, response modification, error handling, and more.
While ASP.NET Core offers built-in middleware like UseRouting, UseAuthorization, etc., there are many scenarios where you’ll want to create your own.
In this article, we’ll explore:
-
What middleware is
-
Why and when to use custom middleware
-
How to create and register custom middleware
-
Real-world examples
-
Best practices
🔧 What is Middleware?
Middleware in ASP.NET Core is software that's assembled into the HTTP request pipeline. Each piece of middleware:
-
Processes an incoming request
-
Can optionally pass the request to the next component
-
Optionally processes the response on the way back
Conceptually, it looks like a chain:
Request --> Middleware 1 --> Middleware 2 --> Middleware 3 --> ... --> Response
📝 Why Create Custom Middleware?
You should consider writing custom middleware when:
-
You want reusable, centralized behavior (like logging or metrics)
-
You need to intercept or transform requests or responses
-
Built-in middleware doesn’t meet your specific need
📦 Project Setup
Let’s build a simple ASP.NET Core Web API project to demonstrate.
dotnet new webapi -n CustomMiddlewareDemo
cd CustomMiddlewareDemo
🔨 Example 1: Logging Request Duration
✨ Purpose:
Log how long each HTTP request takes.
📁 Step 1. Create the Middleware
File: Middleware/RequestTimingMiddleware.cs
using Microsoft.AspNetCore.Http;
using System.Diagnostics;
using System.Threading.Tasks;
using System;
namespace CustomMiddlewareDemo.Middleware
{
public class RequestTimingMiddleware
{
private readonly RequestDelegate _next;
public RequestTimingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
var stopwatch = Stopwatch.StartNew();
await _next(context); // Call next middleware
stopwatch.Stop();
var elapsedMs = stopwatch.ElapsedMilliseconds;
Console.WriteLine($"⏱️ [{DateTime.Now}] Request {context.Request.Method} {context.Request.Path} took {elapsedMs}ms");
}
}
}
📁 Step 2. Create an Extension Method
File: Middleware/RequestTimingMiddlewareExtensions.cs
using Microsoft.AspNetCore.Builder;
namespace CustomMiddlewareDemo.Middleware
{
public static class RequestTimingMiddlewareExtensions
{
public static IApplicationBuilder UseRequestTiming(this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestTimingMiddleware>();
}
}
}
Join the conversation! Your thoughts help the community grow.