How to Use Conditional Middleware in ASP.NET Core
By FoxLearn 2/26/2025 4:38:45 AM 51
Middleware components in ASP.NET Core can inspect, modify, or route requests and responses, and are integral to the request pipeline. This article will discuss advanced operations with middleware in ASP.NET Core, using conditional logic to control the flow of the request pipeline.
The Use, Run, and Map Methods
In ASP.NET Core, there are several methods for configuring middleware in the request pipeline:
Use: This method registers a middleware delegate and allows the pipeline to continue to the next middleware in sequence. It can also be used to short-circuit the pipeline if necessary.
Run: This method executes a middleware delegate and does not proceed to the next middleware in the pipeline.
Map: This method conditionally executes middleware based on the request path.
Each of these methods plays a role in configuring how the request and response processing occurs.
Registering Middleware in ASP.NET Core
Middleware is registered in the Configure
method of the Startup
class using the Use*
methods.
For example, How to register a custom middleware:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseMyCustomMiddleware<MyCustomMiddleware>(); }
Note that the middleware components are executed in the order they are registered.
The Invoke Method
Each middleware component includes an Invoke
method, which accepts an HttpContext
instance as an argument. This method is where the middleware can process the request, either before or after calling the next middleware in the pipeline.
Here’s an example of a typical Invoke
method:
public async Task Invoke(HttpContext context) { // Code executed before the next middleware is called await _next.Invoke(context); // Call the next middleware in the pipeline // Code executed after the next middleware is called }
Branching the HTTP Pipeline in ASP.NET Core
The Map
and MapWhen
methods enable you to branch the HTTP pipeline based on conditions.
Example of Map
Method
The Map
method is used to conditionally execute middleware based on the request path.
Here’s an example where requests are mapped to different branches based on their URL path:
public class Startup { private static void MapRequestX(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("This is MapRequestX"); }); } private static void MapRequestY(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync("This is MapRequestY"); }); } public void Configure(IApplicationBuilder app) { app.Map("/requestX", MapRequestX); app.Map("/requestY", MapRequestY); app.Run(async context => { await context.Response.WriteAsync("Default response"); }); } }
Example of MapWhen
Method
The MapWhen
method allows branching the pipeline based on a custom condition defined by a predicate.
Here’s an example where requests with the content type application/json
are processed by a specific middleware:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.MapWhen(context => context.Request.ContentType.Equals("application/json", StringComparison.OrdinalIgnoreCase), builder => { builder.Run(async context => { await context.Response.WriteAsync("JSON Content-Type Detected"); }); }); app.Run(async context => { await context.Response.WriteAsync("Default response for non-JSON requests"); }); }
Conditional Middleware Execution with UseWhen
The UseWhen
method provides a way to execute middleware conditionally, similar to MapWhen
, but without short-circuiting the pipeline. The middleware configured within UseWhen
will execute if the condition is true, but the subsequent middleware will continue to execute regardless.
Here’s an example that demonstrates conditional middleware execution based on the request path:
app.UseWhen(context => context.Request.Path.StartsWithSegments("/admin"), builder => { builder.Use(async (context, next) => { // Perform some logic before proceeding with the pipeline if (!context.User.Identity.IsAuthenticated) { context.Response.StatusCode = 403; // Forbidden await context.Response.WriteAsync("Access Denied"); return; } await next.Invoke(); // Continue processing the pipeline }); });
In this example, the middleware checks if the request path starts with /admin
. If the request is not from an authenticated user, it immediately returns a "403 Forbidden" response. Otherwise, it continues processing the request.
Using UseWhen
to Execute Middleware for Specific Routes
Here’s a more specific example where a piece of middleware is applied to API requests only:
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), builder => { builder.UseCustomMiddleware(); // Apply custom middleware to /api routes only });
The difference between UseWhen
and MapWhen
is that UseWhen
doesn’t branch the pipeline but adds middleware to be executed conditionally. Middleware that is registered inside a UseWhen
block still continues through the pipeline after being processed.
ASP.NET Core’s middleware pipeline provides several ways to conditionally execute middleware. The Map
and MapWhen
methods allow branching the pipeline based on conditions, while UseWhen
lets you apply middleware conditionally to certain paths or predicates.