- Home
- .NET tutorials
- How to create and add custom middleware in ASP.NET Core
How to create and add custom middleware in ASP.NET Core
Published: Monday 4 March 2024
The great thing about ASP.NET Core is that it provides a number of built-in middleware components.
Creating a custom middleware
As part of the WebApplication type used in Program.cs, there is a Use extension method. This extension method requires two parameters:
context- An instance of theHttpContexttypenext- Runs the next method in the middleware chain
As we have an instance of the HttpContext, we are able to make changes to the response before it has started to be written.
X-Frame-Options header should be set to SAMEORIGIN.
// Program.cs
app.Use(async (context, next) =>
{
context.Response.Headers.Append("X-Frame-Options", "SAMEORIGIN");
await next();
});
This is a security feature that ensures that iframes can only be loaded in the same origin.
next parameter is invoked after it. What happens if we don't include that?
Short-circuiting
If we don't invoke the next parameter, then none of the other middleware methods in the chain will be run.
// Program.cs
app.Use(async (HttpContext context, Func<Task> next) =>
{
context.Response.Headers.Append("X-Frame-Options", "SAMEORIGIN");
//await next();
});
This is known as short-circuiting, or terminal middleware. If we run a Web API request in this instance, the X-Frame-Options header would get added to the HTTP response, but there is a good chance that the Web API response would not get returned.
Terminal middleware prevents an ASP.NET Core Web API response being returned
Terminal middleware can also be used by calling app.Run. This might be a good idea if we want to write our own holding page as it passes in the HttpContext type as the parameter.
// Program.cs
app.Run(async (context) =>
{
await context.Response.WriteAsync("<p>Holding page</p>");
});
Writing to the response after next has been called
If writing to the HTTP response, it's generally a good idea to write to it before calling the next() method.
// Program.cs
app.Use(async (HttpContext context, Func<Task> next) =>
{
await next();
context.Response.Headers.Append("X-Frame-Options", "SAMEORIGIN");
});
In this instance, if we executed an ASP.NET Core Web API endpoint, the X-Frame-Options would not be added to the HTTP response headers as the HTTP response has already started.
Custom middleware in it's own class
As well as using app.Use, custom middleware can be written to it's own class.
// HeaderMiddleware.cs
public class HeaderMiddleware
{
private readonly RequestDelegate _next;
public HeaderMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
httpContext.Response.Headers.Append("X-Frame-Options", "SAMEORIGIN");
await _next(httpContext);
}
}
A next parameter is passed into the constructor which is stored as a private readonly field.
Invoke method, passing in an instance of HttpContext. We add our X-Frame-Options header to the HTTP response with a value of SAMEORIGIN before invoking the next method passing in the HttpContext instance as a parameter.
WebApplication instance in Program.cs. We do that by calling the app.UseMiddleware extension method:
// Program.cs
app.UseMiddleware<HeaderMiddleware>();
Watch our video
Watch our video where we show how to add custom middleware to an ASP.NET Core Web API and demonstrate what happens with short-circuiting and writing to the HTTP response after the next middleware in the chain has been invoked.
Latest tutorials
File logging in ASP.NET Core made easy with Serilog
Learn how to add file logging to an ASP.NET Core app using Serilog, including setup, configuration, and writing logs to daily rolling files.