Middleware In .NET Core

In this article I will explain middleware concepts as follows,
  1. What is middleware
  2. Middleware Order of execution
  3. Create middleware using IApplicationBuilder
  4. Run, Use and Map method
  5. Custom middleware
  6. Built-in middleware

What is middleware?

 
Middleware is just a simple class that consists of encapsulated information into an application pipeline to deal with the https request response pipeline.
 
Every part of this class has the option to pick whether to give the request to the next pipeline, and can play out specific activities when the following request passes in the pipeline.
 
In this case Request delegates are utilized to construct the request pipeline.
 
The request delegates handle every HTTP request.
 
Request delegates are designed to configure the Run, Map, and Use method on the IApplicationBuilder type that is passed into the Configure method in the Startup class. An individual request delegate can be determined in-line as a lambda expression, or it can be designed in a reusable class.
 
These reusable classes are middleware, or middleware parts. Each middleware part in the request pipeline is liable for invoking the next pipeline, or shortcircuiting the request.
 
Every component of middleware plays a specific role, we can mix up the role but this is not a good approach in software designed architechture.
 
So we should create for the specific purpose of of single middleware.
 
For example if we see how microsoft created so much middleware for specific problems.
 
I will explain in just a bit about built in middleware here.
 

Middleware Order of Execution

 
The middleware Order of Execution plays a  very important role so you have to take care of it very precisely,  otherwise you may get unexpected behavior.
 
So suppose you have 3 middleware -  M1, M2, M3 in sequential order, then it will invoke in the same order and then respond in the reverse direction.
 
Lets take another example here.
  1. UseAuthentication();  
  2. app.UseAuthorization();   
Here we have set first authentication then authorization, so the order matters, because in real projects we do first authentication, then authentication.
 
Please refer to this image as it is taken from MS doc reference.
Middleware In .NET Core
 

Create middleware using IApplicationBuilder

 
We can create middleware in the Configure method of the Startup class using IApplicationBuilder interface.
 
Here in this following example I will add a simple middleware using Run method that will return a string "Hello my first middleware," on every request.
  1. public class Startup {  
  2.     public Startup() {}  
  3.     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {  
  4.         // here i have configure middleware using IApplicationBuilder with Run merhod.    
  5.         // I will explain Run method in details just a bil.    
  6.         app.Run(async (context) => {  
  7.             await context.Response.WriteAsync("Hello my first middleware");  
  8.         });  
  9.         // I have removed hereother code for the clarity..    
  10.     }  
  11. }   
In this example I have used Run() method. This is a extension merhod of IApplicationBuilder interface.
 
Here I have created middleware using lambda expression, but we can also create it using a private method like this,
  1. public class Startup {  
  2.     public Startup() {}  
  3.     public void Configure(IApplicationBuilder app, IHostingEnvironment env) {  
  4.         app.Run(TestMiddleware);  
  5.     }  
  6.     private Task TestMiddleware(HttpContext context) {  
  7.         return context.Response.WriteAsync("Hello TestMiddleware");  
  8.     }  
  9. }   

Run, Use and Map method

 
Run() method behaves like a terminal middleware delegate to the application's request pipeline.
 
It will not invoke the next  one in the pipeline.
 
For example,
  1. // Middleware 1    
  2. app.Run(async (context) => {  
  3.     await context.Response.WriteAsync("Middleware 1");  
  4. });  
  5. // Middleware 2    
  6. app.Run(async (context) => {  
  7.     await context.Response.WriteAsync("Middleware 2");  
  8. });   
So in this example only // Middleware 1 will execute then after that it terminated the request.
 
When you right click and go to definition for Run() method you will get this signature of Run method,
 
public static void Run (this is IApplicationBuilder app, RequestDelegate handler)
 
Use() is also a function of IApplicationBuilder that is used to handle the request or call the given next function.
 
So as we have seen in the Run() method it doesn't invoke next function but Use  does that.
  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env) {  
  2.     app.Use(async (context, next) => {  
  3.         await context.Response.WriteAsync("Middleware 1");  
  4.         await next();  
  5.     });  
  6.     app.Run(async (context) => {  
  7.         await context.Response.WriteAsync("Middleware 2");  
  8.     });  
  9. }   
I use first Use method then after that Run() method, so we will get the output for both Map() methods used for the branches the request pipeline based on matches condition.
 
If the request path matches with the given path, the branch is executed.
  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env) {  
  2.     app.Map("/maptest", HandleMapMethod);  
  3. }  
  4. private static void HandleMapMethod(IApplicationBuilder app) {  
  5.     app.Run(async context => {  
  6.         await context.Response.WriteAsync("Map method testing");  
  7.     });  
  8. }   

Custom middleware

 
Here in this section i will explain how to create and add your own custom middleware.
 
Custom middleware is also  kind of the same as built in middleware but we create our own when a few requirement don't match with inbuilt middleware.  In custom middleware we should also have RequestDelegate type parameter in the constructor.
 
Now at this time Microsoft in Visual Studio is provided a template for Middleware.
 
So for thatRight click on your solution project or folder where you want to add middleware class then select Add -> New Item. This will open Add the popup.
 
Search the word "middleware" in the top right search box and you will get middleware template class.
 
Middleware In .NET Core
  1. public class MyCustomMiddleware {  
  2.     private readonly RequestDelegate _next;  
  3.     public MyCustomMiddleware(RequestDelegate next) {  
  4.         _next = next;  
  5.     }  
  6.     public Task Invoke(HttpContext httpContext) {  
  7.         // you can write here whatever you want    
  8.         return _next(httpContext);  
  9.     }  
  10. }  
  11. public static class MyMiddlewareExtensions {  
  12.     public static IApplicationBuilder UseMyCustomMiddleware(this IApplicationBuilder builder) {  
  13.         return builder.UseMiddleware < MyCustomMiddleware > ();  
  14.     }  
  15. }  
then you need to add your custom middleware in configure method,
  1. public void Configure(IApplicationBuilder app, IHostingEnvironment env) {  
  2.     app.UseMyCustomMiddleware();  
  3.     app.Run(async (context) => {  
  4.         await context.Response.WriteAsync("Hello World!");  
  5.     });  
  6. }   

Built-in middleware

 
ASP.NET core provide the following middleware components,
 
 Middleware Description 
 Authentication  Provides authentication support.
 CORS  Configures Cross-Origin Resource Sharing.
 Routing   Defines for request routes.
 Session
Static Files 
Diagnostics  
 MVC
 Provides support for user sessions. 
 Provides support for serving static files, and directory browsing.  
Several separate middlewares that provide a developer exception page, exception handling,
status code pages, and the default web page for new apps.
Processes requests with MVC/Razor Pages.
 
 
Thank you for taking your valuable time to read the full article.


Similar Articles