joydip_kanjilal
Contributor

How to use conditional middleware in ASP.NET Core

how-to
Aug 05, 20196 mins
C#Microsoft .NETSoftware Development

Take advantage of advanced operations such as conditional branching when working with middleware in ASP.NET Core.

multicolor flowchart design 91521493
Credit: Thinkstock

ASP.NET Core is an open source, cross-platform, extensible, lean, and modular framework from Microsoft that can be used for building high-performance web applications. Middleware components can be used in the ASP.NET Core request pipeline to customize the way requests and responses are handled.

ASP.NET Core middleware components can also be used to inspect, route, or modify the request and response messages that flow through the pipeline. This article presents a discussion of how we can perform some advanced operations with middleware in ASP.NET Core.

Create an ASP.NET Core MVC project

First off, let’s create an ASP.NET Core project in Visual Studio. Assuming that Visual Studio 2017 or Visual Studio 2019 is installed in your system, follow the steps outlined below to create a new ASP.NET Core project in Visual Studio.

  1. Launch the Visual Studio IDE.
  2. Click on “Create new project.”
  3. In the “Create new project” window, select “ASP.NET Core Web Application” from the list of templates displayed.
  4. Click Next.
  5. In the “Configure your new project” window, specify the name and location for the new project.
  6. Click Create.
  7. In the “Create New ASP.NET Core Web Application” shown next, select .NET Core as the runtime and ASP.NET Core 2.2 (or later) from the drop-down list at the top.
  8. Select “Web Application (Model-View-Controller)” as the project template to create a new ASP.NET Core application. 
  9. Ensure that the check boxes “Enable Docker Support” and “Configure for HTTPS” are unchecked as we won’t be using those features here.
  10. Ensure that Authentication is set as “No Authentication” as we won’t be using authentication either.
  11. Click Create, 

Following these steps should create a new ASP.NET Core project in Visual Studio. We’ll use this project in the subsequent sections of this article.

The Use, Run, and Map methods in ASP.NET Core

The Use, Map, and Run methods are used to configure the HTTP pipeline in ASP.NET Core. Here’s a glimpse at each of these methods and their purpose.

  • Use — this method will execute the delegate and then move to the next step in the pipeline. The Use method can also be used to short-circuit the pipeline.
  • Run — this method will execute a delegate and return the result. 
  • Map — this method will execute a delegate conditionally and return the result. 

Register middleware in ASP.NET Core

A middleware component in ASP.NET Core is registered in the Configure method of the Startup class. The Use* extension methods are used to register middleware. Here is the syntax for registering a middleware component.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseMyCustomMiddleware<MyCustomMiddleware>();
}

It should be noted that middleware components are executed in the order in which they are registered.

The Invoke method in ASP.NET Core

Each middleware component contains an Invoke method. This method accepts a reference to an instance of HttpContext as an argument. A middleware component can perform operations before and after the next middleware component is called. Here is an example of a typical Invoke method:

public async Task Invoke(HttpContext context)
{
    // Write code here that will be executed before the
    // next middleware is called
        await _next.Invoke(context); // call next middleware
    // Write code here that will be executed after the
    //next middleware is called 
}

Branching the HTTP pipeline in ASP.NET Core

The Map extension methods, i.e. Map and MapWhen, are used for branching the pipeline. While Map is used to branch based on a given request path, MapWhen is used to branch based on the result of a given predicate.

The following code snippet illustrates how the Map method can be used for branching the request pipeline.

public class Startup
{
    private static void MapRequestA(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("This is MapRequestA");
        });
    }
    private static void MapRequestB(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("This is MapRequestB");
        });
    }
    private static void MapRequestC(IApplicationBuilder app)
    {
        app.Run(async context =>
        {
            await context.Response.WriteAsync("This is MapRequestC");
        });
    }
    public void Configure(IApplicationBuilder app)
    {
        app.Map("/mapRequestPathA", MapRequestA);
        app.Map("/mapRequestPathB", MapRequestB);
        app.Map("/mapRequestPathB", MapRequestC);
        app.Run(async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    }
   //Other methods
}

The MapWhen method accepts two parameters:

  • A Func predicate
  • A delegate action

You can use the following code snippet in the Configure method of the Startup class to disallow content type “text/html”.

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.MapWhen(context => context.Request.ContentType.Equals
            ("text/xml", StringComparison.InvariantCultureIgnoreCase),
            (IApplicationBuilder applicationBuilder) =>
            {
                applicationBuilder.Run(async context =>
                {
                    await Task.FromResult(context.Response.StatusCode = StatusCodes.Status406NotAcceptable);
                });
            });
            app.UseMvc();
        }

The UseWhen method in ASP.NET Core

The UseWhen method can be used to execute middleware conditionally. The following code snippet illustrates how the UseWhen method can be used to execute a middleware component if the request path starts with “/api”.

app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), applicationBuilder =>
{
    applicationBuilder.UseCustomMiddleware();
});

Note that unlike MapWhen, the UseWhen method continues to execute the later middleware irrespective of whether the UseWhen predicate was true or false. Let’s understand this with an example. Consider the following piece of code:

app.UseMiddlewareA();
app.UseWhen(context => context.Request.Path.StartsWithSegments("/api"), applicationBuilder =>
{
    applicationBuilder.UseMiddlewareB();
});
app.UseMiddlewareC();

If there is no short-circuiting of the middleware, middleware A and C will always be executed. Middleware B will be executed only if the request path starts with “/api”.

In ASP.NET Core there is a chain of middleware components in the request processing pipeline. All requests and responses flow through this pipeline. When a new request arrives, these middleware components can either process the request or pass the request to the next component in the pipeline. For more complex request processing, we can use the Map and MapWhen methods to branch the pipeline and UseWhen to execute middleware conditionally. 

Learn more about middleware and request and response handling in ASP.NET Core:

joydip_kanjilal
Contributor

Joydip Kanjilal is a Microsoft Most Valuable Professional (MVP) in ASP.NET, as well as a speaker and the author of several books and articles. He received the prestigious MVP award for 2007, 2008, 2009, 2010, 2011, and 2012.

He has more than 20 years of experience in IT, with more than 16 years in Microsoft .Net and related technologies. He has been selected as MSDN Featured Developer of the Fortnight (MSDN) and as Community Credit Winner several times.

He is the author of eight books and more than 500 articles. Many of his articles have been featured at Microsoft’s Official Site on ASP.Net.

He was a speaker at the Spark IT 2010 event and at the Dr. Dobb’s Conference 2014 in Bangalore. He has also worked as a judge for the Jolt Awards at Dr. Dobb's Journal. He is a regular speaker at the SSWUG Virtual Conference, which is held twice each year.

More from this author