How to Use Conditional Middleware in ASP.NET Core

By FoxLearn 2/26/2025 4:38:45 AM   51
ASP.NET Core is a powerful, cross-platform framework designed by Microsoft for building high-performance web applications. It is lightweight and modular, allowing developers to configure middleware components that define how HTTP requests and responses are processed.

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.