Back to: ASP.NET Core Tutorials For Beginners and Professionals
ASP.NET Core Middleware with Examples
In this article, I am going to discuss the ASP.NET Core Middleware Components with Examples. Please read our previous article, where we discussed the ASP.NET Core AppSettings.json File with Examples. As part of this article, we are going to discuss the following concepts related to the ASP.NET Core Middleware Components.
- What are the ASP.NET Core Middleware Components?
- Where do we use the Middleware Components in the ASP.NET Core application?
- How to Configure Middleware Components in ASP.NET Core application?
- Examples of using Middleware Components?
- What is the Execution Order of Middleware Components in ASP.NET Core?
- What are Request Delegates in ASP.NET Core?
- What is Use, Run, and Map Methods in ASP.NET Core?
- What is UseDeveloperExceptionPage Middleware Component?
- How to Configure Middleware Components using the Run() and Use() Extension Methods?
- What is the difference Between MapGet and Map Methods?
- Differences Between Mao, Use, and Run Extension Methods?
What are ASP.NET Core Middleware Components?
ASP.NET Core middleware components are modular, reusable components that form the building blocks of the request processing pipeline in an ASP.NET Core application. Middleware components are responsible for handling specific tasks during the processing of incoming HTTP requests and outgoing responses. They enable you to add various functionalities to your application, such as authentication, routing, logging, compression, and more, in a highly modular and customizable manner.
Middleware components are executed in the order they are added to the pipeline, and each component has the ability to process requests, modify responses, or perform other actions before and after passing the request to the next middleware component. This sequential execution allows you to create a flexible and extensible pipeline tailored to your application’s needs.
The ASP.NET Core Middleware Components are the software components (technically, components are nothing but the Methods) that are configured into the Application Request Processing Pipeline to handle the HTTP Requests and Responses. Each middleware component in ASP.NET Core Application performs the following tasks.
- Chooses whether to pass the HTTP Request to the next component in the pipeline. This can be achieved by calling the next() method within the Middleware. In this article will discuss how to Register the Middleware component and call the next() method.
- Can perform certain tasks before and after the next component is invoked in the pipeline.
In ASP.NET Core, many built-in Middleware components are already made available that you can use directly. You can create your own Middleware components in ASP.NET Core Applications if you want. The most important point you need to remember is that in ASP.NET Core, a given Middleware component should only have a specific purpose, i.e., single responsibility.
Where Do We Use Middleware Components in the ASP.NET Core Application?
Some of the examples of using Middleware components in the ASP.NET Core application are as follows.
- We have a Middleware component (UseAuthentication) for authenticating the user.
- We have a middleware component (UseHttpsRedirection) for redirecting HTTP Requests to HTTPS.
- Another Middleware component (UseHttpLogging) is used to log the HTTP Requests and Responses.
- We have another Middleware component (UseDeveloperExceptionPage) that is going to execute when there is an unhandled exception in the development environment.
- Similarly, we have a Middleware Component (UseExceptionHandler) that is used to catch exceptions, log them, and re-execute the request in an alternate pipeline.
- We have a Middleware component (UseStaticFiles) that is used to handle static files such as Images, Javascript. or CSS files, etc.
- We have a Middleware component (UseAuthorization) that is used to Authorize the users while accessing a specific resource.
- The UseRouting adds the End Points Routing Middleware to the Request Processing Pipeline. If you want to define the Route using Pattern or attribute routing, then it is mandatory to use UseRouting Middleware Component.
We generally use the Middleware components to set up the Request Processing Pipeline in the ASP.NET Core Application. If you have worked with previous versions of the .NET Framework, then you may know we use HTTP Handlers and HTTP Modules to set up the Request Processing Pipeline. The Request Processing Pipeline is the pipeline that will determine how the HTTP Requests and Responses are going to be processed in ASP.NET Core Application.
How to Configure Middleware Components in ASP.NET Core (.NET 6) Application?
In .NET 6 Application, we need to configure the Middleware components within the Main() method of the Program class, which is present inside the Program.cs class file. This is the class that is going to run when the application starts, and the application execution is going to start from the Main method, i.e., the Main method is the entry point for any ASP.NET Core Web Application.
When we create a new ASP.NET Core Empty Web Application, then by default, the Program class is created with the Main method, as shown in the below image.
In the above Main method, by default, we have configured two middleware components, i.e., MapGet and Run. If you want to configure any middleware components in any ASP.NET Core Web Applications, then you need to configure it within the Main() method of the Program class by calling the appropriate middleware methods using the WebApplication instance. For a better understanding, please modify the Main Method of the Program class as follows in which we have configured a few Middleware Components using the WebApplication instance, such as UseDeveloperExceptionPage(), UseRouting(), and UseEndpoints().
namespace FirstCoreWebApplication { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); //Configuring Middleware Components into Application Request Processing Pipeline //Configuring UseDeveloperExceptionPage Middleware Component if the Environment is Development if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } //Configuring UseRouting Middleware Component //It matches a request to an endpoint. app.UseRouting(); //Configuring UseEndpoints Middleware Component //It executes the matched endpoint. app.UseEndpoints(endpoints => { endpoints.MapGet("/", async context => { await context.Response.WriteAsync("Hello World!"); }); }); app.Run(); } } }
As you can see in the above code, the Main() method sets up the request processing pipeline with a few middleware components as follows.
- UseDeveloperExceptionPage() Middleware component
- UseRouting() Middleware component
- UseEndpoints() Middleware component
Before understanding the above Built-in Middleware Components in ASP.NET Core Applications, let us first understand what Middleware Components are and How Exactly These Middleware Components Work in ASP.NET Core Web Applications.
Understanding Middleware Components in ASP.NET Core:
In the ASP.NET Core Web Application, the Middleware Component can have access to both the incoming HTTP Request and outgoing HTTP Response. So, a Middleware Component in ASP.NET Core Web Application can
- Handle the incoming HTTP request by generating an HTTP response.
- Process the incoming HTTP request, modify it, and then pass it to the Next Middleware Component that is configured in the Application Request Processing Pipeline.
- Process the outgoing HTTP response, modify it, and then pass it on to either the previous middleware component or to the ASP.NET Core Web Server.
For better understanding, please have a look at the following diagram, which shows how the middleware components are used in the Request Processing Pipeline of the ASP.NET Core Web Application. As shown in the below image, we have configured 3 Middleware Components to the Application Request Processing Pipeline to handle the HTTP Requests and Responses.
We have a Logging Middleware Component. This component logs the request time and then passes the HTTP Request to the next middleware component, i.e., the Static Files Middleware component in the Request Pipeline, for further processing.
As we already discussed, a Middleware Component in ASP.NET Core Web Application may also handle the HTTP Request by generating an HTTP Response. The Middleware Component may also decide not to call the Next Middleware Component in the Request Processing Pipeline. This concept is called Short-Circuiting the Request Processing Pipeline.
For example, we have a Static Files Middleware Component. And if the incoming HTTP request comes for some static files such as Images, CSS files, JavaScript, etc., then this Static Files Middleware component can handle the request and then Short-Circuiting the Request Processing Pipeline by not calling to the Next Middleware Component in the pipeline, i.e., the MVC Middleware Component.
As we already discussed, the ASP.NET Core Middleware Components can have access to both the HTTP Request and Response in the pipeline. So, a middleware component can also process the outgoing response. For example, the logging middleware component, in our case, may log the time when the response is sent back to the client.
What is the Execution Order of Middleware Components in ASP.NET Core Application?
It is very important to understand the execution order of Middleware Components in ASP.NET Core Web Applications. The ASP.NET Core Middleware Components are executed in the same order as they are added to the Request Processing Pipeline. So, we need to take proper care when adding the Middleware Components to the Request Processing Pipeline of the ASP.NET Core Web Application.
As per your Application’s Business Requirements, you may add any number of Middleware Components. For example, if you are developing a static web application with some static HTML pages and images, then you may require only “StaticFiles” middleware components in the Request Processing Pipeline.
But, if you are developing a secure Dynamic Data-Driven Web Application, you may require several Middleware Components such as Logging Middleware, Authentication Middleware, Authorization Middleware, MVC Middleware, etc.
What are Request Delegates in ASP.NET Core?
In ASP.NET Core, Request Delegates are used to build the Request Pipeline, i.e., Request Delegates are used to handle each incoming HTTP request. And you can configure the Request Delegates using the Run, Map, and Use Extension Methods. You can specify a Request Delegate using an in-line anonymous method (called in-line middleware) or specify the Request Delegates using a reusable method. These reusable methods and in-line anonymous methods are called Middleware or Middleware Components. Each Middleware Component in the Request Processing Pipeline is responsible for invoking the Next Component in the Pipeline or Short-Circuiting the Pipeline by not calling the Next Middleware Component.
What is the use of the Use and Run Extension Method in ASP.NET Core Web Application?
In ASP.NET Core Web Application, we can use the “Use” and “Run” Extension Methods to register the Inline Middleware Component into the Request Processing Pipeline. The “Run” extension method allows us to add the terminating middleware (the middleware which will not call the Next Middleware Components in the Request Processing Pipeline). On the other hand, the “Use” extension method allows us to add the middleware components, which may call the next Middleware Component in the Request Processing Pipeline.
If you observe the Main method of the Program class (with .NET 6), then you will see that it gets an instance of WebApplication (with .NET 6), and using that instance along with the extension methods such as Use and Run, it configures the Middleware Components.
As you can see, in the Main method of the Program class, three Middleware Components are registered in the Request Processing Pipeline. They are as follows:
- UseDeveloperExceptionPage() Middleware Component
- UseRouting() Middleware Component
- UseEndpoints() Middleware Component
What is DeveloperExceptionPage Middleware Component?
As you can see, the UseDeveloperExceptionPage() Middleware Component is registered into the pipeline, and this middleware component will come into the picture only when the hosting environment is set to Development. This middleware component is going to execute when there is an unhandled exception occurs in the application, and since it is in Development mode, it is going to show you the details of the exception on the webpage. You can consider this as a replacement for the Yellow Screen of Death. In a later article, we will see the use of this middleware component in detail with examples.
What is UseRouting() Middleware Component?
The UseRouting() middleware component is used to add Endpoint Routing Middleware to the request processing pipeline. Endpoint Routing means it will map the URL (or incoming HTTP Request) to a particular resource. We will discuss this in detail in our Routing articles.
What is the UseEndpoints() Middleware Component?
To use UseEndpoints() Middleware Component. first, you must add the UseRouting() middleware component. In this UseEndpoints() Middleware Component, the routing decisions are going to be taken using the Map extension method. And as part of this UseEndpoints() Middleware Component, we can register multiple URL patterns using the MapGet or Map methods.
For a better understanding, please have a look at the following code. As you can see, in the MapGet Extension Method, we have specified the URL pattern like “/”. This means the domain name only. So, any request with only the domain name is going to be handled by this Middleware Component.
Instead of MapGet, you can also use the Map method, as shown below.
Now run the application, and you should get the output as expected.
UseRouting(): It matches a request to an endpoint.
UseEndpoints(): It executes the matched endpoint.
What is the Difference Between MapGet and Map Extension Methods in ASP.NET Core?
The MapGet Extension Method is going to handle only the GET HTTP Requests, whereas the Map Extension Method is going to handle all types of HTTP requests, such as GET, POST, PUT, & DELETE, etc. in ASP.NET Core Web Application.
How to Configure Middleware Components Using the Run() Extension Method?
Now, let us learn how to configure new Middleware Components using Run Extension Method in the .NET 6 Application. In .NET 6, we need to configure the Middleware Components within the Main method of the Program class. So, modify the Main method of the Program class as follows to add a new custom Inline Middleware Component using the Run Extension Method.
namespace FirstCoreWebApplication { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); //Configuring New Inline Middleware Component using Run Extension Method app.Run(async (context) => { await context.Response.WriteAsync("Getting Response from First Middleware"); }); //This will Start the Application app.Run(); } } }
Now, run the application, and you should get the output as expected, as shown in the below image.
Now, if you go to the definition of the Run Extension Method configuring the Middleware Component, you will see the following signature. So, it basically adds a terminal middleware delegate to the application’s request pipeline.
Here, you can see it is clearly saying that this Extension Method is used for adding terminal middleware. Terminal Middleware is the last middleware component. If you are new to the extension method, please read the article below, where we discussed the extension methods in detail.
https://dotnettutorials.net/lesson/extension-methods-csharp/
You can also see from the above definition of the Run() Extension method that it takes an input parameter of RequestDelegate. Now, if you go to the definition of RequestDelegate, then you will see the following.
As you can see in the above image, the RequestDelegate is a delegate that takes an input parameter of type HttpContext object. If you are new to delegates, I strongly recommend reading the following article, where we discuss the delegates in detail.
https://dotnettutorials.net/lesson/delegates-csharp/
As we already discussed, the middleware components in ASP.NET Core Web Application can have access to both HTTP requests and Responses, and this is because of the above HttpContext object. In our example, to the Run Extension method, we are passing an anonymous method or delegate, and moreover, we are passing the HTTP Context object as an input parameter to the request delegate. The following diagram shows the above.
Note: Instead of passing the request delegate inline as an anonymous method, you can also define the request delegate in a separate class and pass it here, which we will discuss in a later article.
Add one More Middleware Component to the Application Request Processing Pipeline.
To do so, modify the Main method of the Program class as shown below.
namespace FirstCoreWebApplication { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); //Configuring New Middleware Component using Run Extension Method app.Run(async (context) => { await context.Response.WriteAsync("Getting Response from First Middleware"); }); //Configuring New Middleware Component using Run Extension Method app.Run(async (context) => { await context.Response.WriteAsync("Getting Response from Second Middleware"); }); //This will Run Application app.Run(); } } }
Now we have two middleware components registered with the Run() extension method. If you run the application, then you will get the following output.
Getting Response from First Middleware
The output comes from the first middleware component. The reason is when we register a middleware component using the Run() extension method, then that component becomes a terminal component means it will not call the next middleware component in the request processing pipeline.
Configuring Middleware Components Using the Use Extension Method
Then the question that comes to your mind is how to call the next component in the request processing pipeline. The answer is to register your middleware component using the Use extension method, as shown below. As you can see in the below code, in the first Use Extension method, we are passing two input parameters to the anonymous method, i.e., context and next. And then, we call the next method, which will call the next middleware component registered in the Request Processing Pipeline.
namespace FirstCoreWebApplication { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); //Configuring New Middleware Components using Use Extension Method app.Use(async (context, next) => { await context.Response.WriteAsync("Getting Response from First Middleware"); await next(); }); app.Run(async (context) => { await context.Response.WriteAsync("\nGetting Response from Second Middleware"); }); //This will Run Application app.Run(); } } }
Now run the application, and you will see the output as expected, which is coming from both the middleware components, as shown in the below image.
Understanding the Use Extension Method in ASP.NET Core:
The Use extension method adds a middleware delegate defined in-line to the application’s request pipeline. Following is the definition of the Use extension method:
This method is also implemented as an extension method on the IApplicationBuilder interface. This is the reason why we are able to invoke this method using the IApplicationBuilder instance. As you can see from the above definition, this method takes two input parameters. The first parameter is the HttpContext context object, through which it can access both the HTTP request and response. The second parameter is the Func type, i.e., it is a generic delegate that can handle the request or call the next middleware component in the request pipeline.
Note: If you want to send the request from one middleware to the next, you need to call the next method.
Differences Between Run, Map, and Use Extension Method in ASP.NET Core:
- Map: If you want to insert some specific middleware logic for some specific URL, then you can do the same using the Map Extension Method in any ASP.NET Core Application.
- Run: The Run method in ASP.NET Core Application is used to complete the Middleware Execution. That means the Run extension method allows us to add the terminating middleware component. Terminating middleware means the middleware which will not call the next middleware components in the request processing pipeline.
- Use: The Use Extension Method in ASP.NET Core Application allows us to add a new middleware component in the request processing pipeline, which may call the next middleware component.
Key Features of ASP.NET Core Middleware Components
Key features and concepts related to ASP.NET Core middleware components:
- Order of Execution: Middleware components are executed in the order they are registered in the pipeline. This order is important, as it determines how the request is processed and modified at each step.
- Middleware Methods: Middleware components typically have two main methods: InvokeAsync and Invoke. These methods handle the request and can perform actions such as modifying the request, generating a response, or passing the request to the next middleware component in the pipeline.
- Middleware Configuration: Middleware components are configured in the Startup.cs file of your ASP.NET Core application using the app.UseMiddleware<TMiddleware>() method. You can also use extension methods provided by ASP.NET Core to add built-in middleware.
- Short-Circuiting: Middleware components have the option to short-circuit the pipeline by not calling the next middleware component. This is often used for authorization, authentication, and other cases where processing can be halted.
- Custom Middleware: You can create your own custom middleware by implementing the required interfaces or delegate signatures. This allows you to encapsulate specific functionality in a reusable component.
- Built-In Middleware: ASP.NET Core provides a variety of built-in middleware components that address common requirements such as routing, authentication, authorization, exception handling, static file serving, and more.
- Middleware Order: The order in which you register middleware matters. Middleware components are executed from top to bottom, so consider the sequence of execution when adding or configuring components.
- Dependencies and DI: Middleware components can be registered with dependency injection (DI) services, allowing them to access services and configurations needed for their functionality.
So, by using middleware components, you can structure your ASP.NET Core application’s request processing logic into manageable and reusable units. Middleware provides a powerful way to add functionality to your application while keeping your code organized and focused on specific concerns.
In the next article, I am going to discuss the ASP.NET Core Request Processing Pipeline with Examples. In this article, I explain How to use Middleware Components in the ASP.NET Core Application to handle the request processing pipeline with an example. I hope you enjoy this ASP.NET Core Middleware Components with Examples article.
About the Author: Pranaya Rout
Pranaya Rout has published more than 3,000 articles in his 11-year career. Pranaya Rout has very good experience with Microsoft Technologies, Including C#, VB, ASP.NET MVC, ASP.NET Web API, EF, EF Core, ADO.NET, LINQ, SQL Server, MYSQL, Oracle, ASP.NET Core, Cloud Computing, Microservices, Design Patterns and still learning new technologies.
Please write a one section for Web API using .Net Core
Add a section for asp.net core webapi (dotnet new webapi)
Awesomeness
This article is just next to Perfection..
excellent article and explanation