ASP.NET Core Request Processing Pipeline

ASP.NET Core Request Processing Pipeline

In this article, I am going to discuss the ASP.NET Core Request Processing Pipeline with an example. Please read our previous article before proceeding to this article where we discussed Middleware Components in ASP.NET Core application. As part of this article, we are going to discuss the following pointers in detail.

  1. Understanding the ASP.NET Core Request Processing Pipeline.
  2. How to create and register multiple middleware components in ASP.NET Core?
  3. What is the execution order of middleware components in the request processing pipeline?
Understanding the ASP.NET Core Request Processing Pipeline:

In order to understand the Request Processing Pipeline in ASP.NET Core, concept, let us modify the Configure() method of the Startup class as shown below. Here we are registering three middleware components into the request processing pipeline. As you can see the first two components are registered using the Use() extension method so that they have the chance to call the next middleware component in the request processing pipeline. The last one is registered using the Run() extension method as it is going to be our terminating components i.e. it will not call the next component. 

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace FirstCoreWebApplication
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
        }
        public void Configure(IApplicationBuilder app)
        {
            app.Use(async (context, next) =>
            {
                await context.Response.WriteAsync("Middleware1: Incoming Request\n");
                await next();
                await context.Response.WriteAsync("Middleware1: Outgoing Response\n");
            });

            app.Use(async (context, next) =>
            {
                await context.Response.WriteAsync("Middleware2: Incoming Request\n");
                await next();
                await context.Response.WriteAsync("Middleware2: Outgoing Response\n");
            });

            app.Run(async (context) =>
            {
                await context.Response.WriteAsync("Middleware3: Incoming Request handled and response generated\n");
            });
        }
    }
}

Now run the application and see the browser window as shown in the below image.

ASP.NET Core Request Processing Pipeline

Understanding the ASP.NET Core Request Processing Pipeline Execution Order:

In order to understand this, let us compare the above output with the following diagram to understand the ASP.NET Core Request Processing Pipeline in an easier way.

Understanding the ASP.NET Core Request Processing Pipeline Execution Order

When the incoming HTTP request comes, first it receives by the first middleware component i.e. Middleware1 which logs “Middleware1: Incoming Request” in the response stream. So as a result, first, we see this message first on the browser.

Once the first middleware logs the information, then it calls the next() method which will invoke the second middleware in the request processing pipeline i.e. Middleware2.

The second middleware logs the information “Middleware2: Incoming Request” as a result we see this log information after the first log. Then the second middleware calls the next() which will invoke the third middleware in the request pipeline which is Middleware3.

The third middleware handles the request and then produces the response. So, the third information that we see in the browser is “Middleware3: Incoming Request handled and response generated”.

This middleware component is registered using the Run() extension method, so it is a terminal component. So, from this point, the request pipeline starts reversing. That means from this middleware, the control is given back to the second middleware, and the second middleware logs the information as “Middleware2: Outgoing Response” and then give the control back to the first middleware component, and the first middleware component logs the information as “Middleware1: Outgoing Response” as what we see in the browser.

Key Points to remember:
  1. The ASP.NET Core request processing pipeline consists of a sequence of middleware components that are going to be called one after the other.
  2. Each middleware component can perform some operations before and after invoking the next component using the next method. A middleware component can also decide not to call the next middleware component which is called short-circuiting the request pipeline.
  3. The middleware component in asp.net core has access to both the incoming request and the outgoing response.
  4. The most important point that you need to keep in mind is the order in which the middleware components are added in the Configure method of the Startup class defines the order in which these middleware components are going to be invoked on requests and the reverse order for the response. So, the order is critical for defining the security, performance, and functionality of the application.

In the next article, I am going to discuss the wwwroot folder in ASP.NET Core Application. Here, in this article, I try to explain the ASP.NET Core Request Processing Pipeline with an example. I hope this article will help you to understand the Request Processing Pipeline in ASP.NET Core Web Application. 

Leave a Reply

Your email address will not be published. Required fields are marked *