In my previous article, I explained built-in middleware and how to implement in-line middleware. Please refer to the link below for the article.
Now we are going to write a custom middleware so that we can avoid in-line middleware in Program.cs file. Custom middleware will be written in a separate class. Please find the points that we need to keep in mind when writing custom middleware.
The middleware class must include the following:
- A public constructor with a parameter of type RequestDelegate.
- A public method named Invoke or InvokeAsync . This method should return Task.
- The first parameter should be of type HttpContext
- To expose the Middleware, an extension method is created through IApplicationBuilder.
- Additional parameters for constructor and Invok/InvokeAsync can be populated via Dependency Injection.
Let us quickly jump into the Visual Studio and create a middleware. I will be using the below Tools for this tutorial:
- Visual Studio Community Edition 2022 (64-bit) – Preview (Version 17.3.0 Preview 4.0)
- .NET 6.0
- Minimal Web API
- Swagger
There are three approaches to creating custom middleware.
Approach 1
- Right click on Project- > Add-> New Item
- Search for Middleware in the Pop-up window
- Select Middleware Class, providing a meaningful name and click on “Add”
A class will be created as below with the default implementation:
namespace MiddlewareTutorial {
// You may need to install the Microsoft.AspNetCore.Http.Abstractions package into your project
public class LoggingMiddleware {
private readonly RequestDelegate _next;
public LoggingMiddleware(RequestDelegate next) {
_next = next;
}
public Task Invoke(HttpContext httpContext) {
return _next(httpContext);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class LoggingMiddlewareExtensions {
public static IApplicationBuilder UseLoggingMiddleware(this IApplicationBuilder builder) {
return builder.UseMiddleware < LoggingMiddleware > ();
}
}
}
Approach 2
- Add a new class with a meaningful name.
- Add the public constructor with parameter of type RequestDelegate.
- Add a method named Invoke/InvokeAsync with HttpContext as the first parameter and Task as its return type.
- Add an extension method through IApplicationBuilder for exposing the middleware.
The final class will be looks like below:
namespace MiddlewareTutorial {
public class ClassWithNoImplementationMiddleware {
private readonly RequestDelegate _next;
public ClassWithNoImplementationMiddleware(RequestDelegate next) {
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext) {
await httpContext.Response.WriteAsync("Hello Readers!, this from Customer Middleware...");
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class ClassWithNoImplementationMiddlewareExtensions {
public static IApplicationBuilder UseClassWithNoImplementationMiddleware(this IApplicationBuilder builder) {
return builder.UseMiddleware < ClassWithNoImplementationMiddleware > ();
}
}
}
Approach 3
- Create a class with a meaningful name
- Implement the interface IMiddleware
The class will look like the below:
namespace MiddlewareTutorial {
public class ClassWithIMiddlewareInterface: IMiddleware {
public Task InvokeAsync(HttpContext context, RequestDelegate next) {
throw new NotImplementedException();
}
}
}
Let us quickly check a simple custom middleware example and how it can be used in Program.cs. I will use the sample code seen in Approach 2.
public async Task InvokeAsync(HttpContext httpContext) {
await httpContext.Response.WriteAsync("Hello Readers, this is from Custom Middleware...");
}
Now let us use this middleware into Program.cs class.
using MiddlewareTutorial;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment()) {
app.UseClassWithNoImplementationMiddleware();
app.UseSwagger();
app.UseSwaggerUI();
}
app.Run();
The output will look like the below:
Thank you for reading the article. I hope you have achieved an understanding of creating custom middleware. Please leave your feedback in the comments box below.