How to add custom middleware in ASP.NET Core
By FoxLearn 2/4/2025 8:29:12 AM 22
These components, which can either be classes or lambdas, process requests in a specific sequence. While ASP.NET Core provides many built-in middleware options (such as AuthorizationMiddleware and HttpsRedirectionMiddleware), developers can also create custom middleware to handle specific needs.
Step 1: Create a Middleware Class
To create custom middleware in ASP.NET Core, you’ll typically follow a specific pattern:
- The class should have a constructor that accepts a
RequestDelegate
parameter (to invoke the next middleware in the pipeline) and any dependencies needed. - The class should have an
InvokeAsync()
method that accepts anHttpContext
parameter. This method can then perform three key tasks:- Inspect or modify the request via
HttpContext.Request
. - Call the next middleware using the
RequestDelegate
. - Inspect or modify the response via
HttpContext.Response
.
- Inspect or modify the request via
For example, how to create a middleware class that logs both request and response headers:
public class HeadersMiddleware { private readonly RequestDelegate _nextMiddleware; private readonly ILogger _logger; public HeadersMiddleware(RequestDelegate nextMiddleware, ILogger<HeadersMiddleware> logger) { _nextMiddleware = nextMiddleware; _logger = logger; } public async Task InvokeAsync(HttpContext context) { // 1. Inspect the request if (context.Request.Headers.TryGetValue("Debug", out var debug)) { _logger.LogInformation($"Has Debug request header: {debug}"); } // 2. Call the next middleware in the pipeline await _nextMiddleware(context); // 3. Inspect the response if (context.Response.Headers.TryGetValue("DebugInfo", out var debugInfo)) { _logger.LogInformation($"Has DebugInfo response header: {debugInfo}"); } } }
In this example, the HeadersMiddleware
class logs the presence of specific headers in both the request and response. You can modify this code to suit your needs, such as logging additional information or performing custom actions.
Step 2: Register the Middleware Using app.UseMiddleware()
Once your custom middleware is created, you need to register it in the application's request pipeline. This is done using the app.UseMiddleware<T>()
method in the Program.cs
or Startup.cs
file, depending on the version of ASP.NET Core you're using.
For example, how to register the HeadersMiddleware
in the pipeline:
// Register services and other middleware var app = builder.Build(); app.UseHttpsRedirection(); // Adds HttpsRedirectionMiddleware app.UseAuthorization(); // Adds AuthorizationMiddleware // Register the custom middleware app.UseMiddleware<HeadersMiddleware>(); // Further middleware registrations app.Run();
In versions prior to .NET 6, middleware is registered in the Configure
method of Startup.cs
.
The order in which middleware is registered matters. Middleware components are executed in the order they are added to the pipeline. In the example above, HeadersMiddleware
is added at the end of the pipeline, meaning it will run after the built-in middlewares like HttpsRedirectionMiddleware
and AuthorizationMiddleware
.
To test that your custom middleware is functioning as expected, you can send a request using a tool like Postman. Below is an example of the log output from the HeadersMiddleware
:
info: HeadersMiddleware[0] Has Debug request header: enabled info: HeadersMiddleware[0] Has DebugInfo response header: DB took 5 seconds
This shows that the middleware is correctly inspecting and logging the headers from both the request and the response.
When middleware components are registered using app.UseMiddleware()
, their order in the pipeline matters. Middleware is executed in the same order in which it is registered. To better understand how this works, let’s consider a scenario where we register three middleware components:
app.UseMiddleware<FirstMiddleware>(); app.UseMiddleware<SecondMiddleware>(); app.UseMiddleware<ThirdMiddleware>();
In each of these middleware components, let’s assume that the InvokeAsync()
method logs a message whenever it handles a request or response. The order of execution for a request would look like this:
FirstMiddleware got request. Calling next middleware. SecondMiddleware got request. Calling next middleware. ThirdMiddleware got request. Calling next middleware. ThirdMiddleware got response. SecondMiddleware got response. FirstMiddleware got response.
As you can see, the InvokeAsync()
methods are called in the order in which the middleware is registered. The request flows through the middleware in a top-down order, while the response flows bottom-up.
Custom middleware in ASP.NET Core allows you to extend the request pipeline to meet the specific needs of your application. By creating a custom middleware class and registering it using app.UseMiddleware()
, you can add functionality such as logging, request modification, or response handling.
Remember that the order in which middleware is registered is crucial, as it dictates the sequence of execution during both the request and response phases.
- How to supply IOptions in ASP.NET Core
- Logging requests and responses in ASP.NET Core
- How to manually validate a model in a controller in ASP.NET Core
- How to disable ModelStateInvalidFilter in ASP.NET Core
- How to Turn Off Startup Logging in ASP.NET Core
- Dependency inject BackgroundService into controllers
- How to Configure JSON Serializer options in ASP.NET Core
- How to use Razor View Engine in ASP.NET Core