Back to: ASP.NET Core Tutorials For Beginners and Professionals
ASP.NET Core Request Processing Pipeline
In this article, I will discuss the ASP.NET Core Request Processing Pipeline with Examples. Please read our previous article before proceeding to this article, where we discussed Middleware Components in ASP.NET Core Applications with Examples.
What is the ASP.NET Core Request Processing Pipeline?
The ASP.NET Core request processing pipeline is a series of middleware components that handle incoming HTTP requests and responses in an ASP.NET Core Web application. Each middleware component is responsible for a specific task, such as authentication, routing, logging, caching, encryption and decryption, response generation, etc. The pipeline is configured in the Program class of an ASP.NET Core application.
The following diagram shows the complete request processing pipeline for ASP.NET Core MVC, Web API, and Razor Pages application.
The above diagram shows the ASP.NET Core Request Processing Pipeline and the sequence in which middleware components should registered and executed when a request is processed in an ASP.NET Core application. Let us understand each step in the Request Processing Pipeline:
Request: This is where the incoming HTTP request enters the pipeline. Each middleware component in the pipeline can inspect, modify, or pass the request to the next component.
ExceptionHandler: This middleware is often used to handle exceptions globally. If an unhandled exception occurs, it handles it, logs it, and returns a proper error response, usually a custom error page or a JSON error message.
HSTS (HTTP Strict Transport Security): This middleware enforces strict security policies, telling browsers to only interact with the application over HTTPS. This means this middleware ensures that the application only serves content over HTTPS and prevents any HTTP requests by enforcing strict transport security policies. This middleware is often used in production environments to enhance security.
HttpsRedirection: This middleware redirects HTTP requests to HTTPS. By redirecting any HTTP request to HTTPS, this middleware ensures that all traffic is encrypted for security.
Static Files: This middleware enables static files like HTML, CSS, JavaScript, and images to be served directly without passing them through the rest of the pipeline. This is useful for files that don’t need processing.
Routing: This middleware maps the incoming request to a route, allowing the application to handle it appropriately. Based on URL patterns and route configurations defined in the application, this middleware determines which controller and action will handle the incoming HTTP request.
CORS (Cross-Origin Resource Sharing): This middleware handles CORS policies (cross-origin requests), allowing or denying requests from different origins. CORS is important for accessing resources from different domains and is essential for APIs used by frontend applications hosted on different origins.
Authentication: This middleware handles the authentication or identity of the user or client making the request by validating credentials (e.g., JWT tokens, cookies, etc.). It ensures that the user is authenticated before reaching certain parts of the application.
Authorization: This middleware determines whether an authenticated user is allowed to access a specific resource or endpoint. It checks if the authenticated user has permission to access the requested resource.
Custom Middlewares (Custom1, Custom…): This represents any custom middleware components you may have added to the pipeline. These custom middleware components can perform various operations on the request or response, such as logging, request modification, caching, modifying headers, custom validation, etc.
Endpoint: This is the target of the request, such as a controller action in MVC, Web API, or a Razor Page. The endpoint processes the request and generates a response.
Response: After the endpoint generates a response, it goes back through the pipeline, allowing each middleware component to modify it before sending it back to the client.
Example to Understand ASP.NET Core Request Processing Pipeline
To understand the Request Processing Pipeline in ASP.NET Core Web Application, first, let us modify the Main() Method of the Program class as shown below. Here, we are registering three middleware components into the Request Processing Pipeline. As you can see, the first two middleware components are registered using the Use() extension method, so 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 will be our terminating components, i.e., it will not call the next component.
namespace FirstCoreWebApplication { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); //Configuring Middleware Component using Use and Run Extension Method //First Middleware Component Registered using Use Extension Method app.Use(async (context, next) => { await context.Response.WriteAsync("Middleware1: Incoming Request\n"); //Calling the Next Middleware Component await next(); await context.Response.WriteAsync("Middleware1: Outgoing Response\n"); }); //Second Middleware Component Registered using Use Extension Method app.Use(async (context, next) => { await context.Response.WriteAsync("Middleware2: Incoming Request\n"); //Calling the Next Middleware Component await next(); await context.Response.WriteAsync("Middleware2: Outgoing Response\n"); }); //Third Middleware Component Registered using Run Extension Method app.Run(async (context) => { await context.Response.WriteAsync("Middleware3: Incoming Request handled and response generated\n"); //Terminal Middleware Component i.e. cannot call the Next Component }); //This will Start the Application app.Run(); } } }
Now run the application, and you should get the following output in the browser.
Understanding ASP.NET Core Request Processing Pipeline Execution Order:
Let us compare the above output with the following diagram to understand the ASP.NET Core Request Processing Pipeline more easily.
When the incoming HTTP request arrives, it is first received by the first middleware component, Middleware1, which logs “Middleware1: Incoming Request” in the response stream. As a result, we first see this message on the browser. Once the first middleware logs the information, it calls the next() method, invoking the second middleware in the request processing pipeline, 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(), invoking the third middleware in the request processing pipeline, 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”.
The third middleware component is registered using the Run() Extension Method and is a terminal middleware component. So, from this point, the request pipeline starts reversing. That means the control is returned to the second middleware from this middleware. The second middleware logs the information as “Middleware2: Outgoing Response” and then gives the control back to the first middleware component, and the first middleware component logs the information as “Middleware1: Outgoing Response” as we see in the browser.
Key Points to Remember:
- The ASP.NET Core Request Processing Pipeline consists of a sequence of Middleware Components that will be called one after the other.
- Each Middleware Component can perform some operations before and after invoking the next Middleware 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.
- The Middleware Component in ASP.NET Core has access to both the incoming request and the outgoing response.
The most important point is that the order in which the Middleware Components are added in the Main method of the Program class defines the order in which these Middleware Components will be invoked on requests and the reverse order for the response. So, the order is critical for defining the application’s Security, Performance, and Functionality.
In the next article, I will discuss the wwwroot folder in ASP.NET Core Application. In this article, I try to explain the ASP.NET Core Request Processing Pipeline with an example. I hope you enjoy this article.
doing an awesome job.. Thanks:)
great article ,helps me a thanks
Thanks for sharing information.. Great efforts