Exploring ASP.NET Core Middleware

Debasis Saha  Print 
23 Aug 2018
 
Intermediate
1.32K

Microsoft introduced a new feature called Middleware in the ASP.Net Core applications. It is a new concept in the programming language. Basically, Middleware is just a class or component which fired on every request received in the Asp.Net Core Applications. In the previous version of ASP.Net application, there are two different request pipeline exists namely HttpHandlers and HttpModules. Middleware is just similar to like these Http action pipes which can be configured and executed in the both side.

WHAT IS MIDDLEWARE?

In Asp.Net Core, Middleware actually controls how applications behave on the HTTP request. Actually, Middleware are depending upon classes which creates a pipeline which control the request and response flow in the systems. Every section of the middleware can handle either request or response or both. Each section of the middleware also decide whether the related request or response will move to the next section of the pipeline or not. In this way, we can develop a system flow by the help of middleware in the applications which basically handle the request situations which may be not handled properly by the core applications. In the official site of ASP.NET Core, Microsoft provides an excellent image in which they demonstrate the main behavior of the middleware –

So, in simple word, Middleware can :

  • Generate an HTTP response against the incoming HTTP request.

  • Can be accept an incoming HTTP request, and then pass that request to the next middleware

  • Can be populate an HTTP response and pass that response to another middleware or web server.

So every middleware component can execute any specify task before and after the next allotted component in the middleware pipeline is invoked. These request operations deleted can be configured by using Run, Map and Use extensions methods. Any individual or independent request deleted can be executed or mentioned in-line as an anonymous method or it can also be defined as a reusable class. These reusable class or in-line anonymous methods are normally known as middleware components. So, every component in the middleware is responsible for executing the next component in the pipeline.

BUILT-IN MIDDLEWARE

Just like other features, Microsoft introduced so many inbuild middleware with the Asp.Net Components. In this section, we will discuss about some of the build-in middleware.

Middleware
Description
Order
Authentication
It is used to provide the authentication support for the application.
It need to executed before HttpContext.User
CORS
It is used for configures Cross-Origin Resource Sharing.
It need to execute before execution of the CORs related components.
Diagnostics
It is used to configures diagnostics
It will execute before components
Forwarded Headers
This middleware is used to forwards proxy related headers into the current request.
It need to execute before component executions.
HTTP Method Override
This middleware provides us for the incoming POST request so that method can be overwritten.
It will execute before the components consumes these this.
HTTPS Redirection
It is used to redirect all HTTP request to the HTTPs Service.
It will execute before the components consumes these this.
HSTS
HSTS is one of the important middleware. HSTS stands for HTTP Strick Transport Security. This middleware layer increased the security with a special response header.
It need to execute before response are sent to the middle or after the request send by the components.
MVC
This middleware normally handled all the requests send or receive from the MVC or Razor pages.
It executed if response match with the route.
Response Caching
This middleware provide support related to cached the response from the application
It need to execute before any components which need to cached.
Response Compression
This middleware compressed the response result which receives against any request.
It need to execute before any components which need to compressed.
Request Localization
It provides the localization support.
It need to execute before any components which need to use localized data.
Routing
This middleware provides the definition of the request routes.
It need to executed when any route match with the response.
Session
This middleware provides the support for maintain or manage user login sessions.
It need to execute before any components which need to use related data.
Static Files
This middleware provide support for accessing static files including directory browsing.
It need to execute before any components match with the current solution.
URL Rewriting
This middleware provides the support for rewriting the request URLS and also redirect the request to the next components.
It need to execute the components before that components consumes.
Web Sockets
This middleware is simply activated the WebSocket’s protocol.
It need to execute before any components accept WebSocket requests.

CONFIGURING MIDDLEWARE

So, if we want to use middleware in our application, then we need to configure middleware in our application. For doing this, we need to use Configure() of Startup class where we can use the instance of IApplicationBuilder. In the below example, we use a single middleware with the help of Run method and it will return “Beginning to Middleware” as a string for each request.

public class Startup
{
 public Startup()
 {
 } 
 public void Configure(IApplicationBuilder application, IHostingEnvironment appEnv)
 { 
 application.Run(async (context) =>
 { 
 await context.Response.WriteAsync("Beginning to Middleware…"); 
 }); 
 }
}

In the above code block example, Run() actually is an extension of IApplicationBuilder instance. This extension method basically adds a middleware into the application request pipeline. This method accepts a RequestDelegate parameters which handles any request into the application. The main signature of the Run() is as below –

public static void run (this IApplicationBuilder app, RequestDelegate handler)

Since, this method accepts a RequestDelegate as a parameter, means that it can accept the HttpContext as parameter and it return as Task. That’s why we use lambda expression for returning the string in the above example. We can also specify a separate asynchronous function for returning the result and then that function need to invoke within the Run() as below:-

public void Configure(IApplicationBuilder application, IHostingEnvironment appEnv)
{
 application.Run(FirstMiddleware);
}

private async Task FirstMiddleware (HttpContext context) 
{
 await context.Response.WriteAsync("Beginning to Middleware…");
}

Similar the above example, we can define multiple middleware components within the ASP.NET application which need to be executed sequentially. But for using multiple middleware, we can’t use the Run() since this method add a terminal middleware. For that reason, it can’t be executing the next middleware. In this situation, we need to use Use() extension method for invoke multiple middleware components in our application. The signature of the Use() method is quite similar to the Run() method except that it accept next parameter to execute the next middleware components in the row. The below code demonstrates the same which will execute two middleware components.

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
 application.Run(async (context,next) =>
{ 
 await context.Response.WriteAsync("Beginning to Middleware…"); 
}); 

application.Run(async (context) =>
{ 
 await context.Response.WriteAsync("Beginning Of Middlewar2"); 
});
}

CREATING A CUSTOM MIDDLEWARE

So, as per the discussions till now, it is clear that middleware basically defines the current step process which need to be executed and also, after completing each step it directed to next step for further execution. So, as per our requirement we need to build multiple middleware in the pipeline of request and write all code within the configure() is not good idea since it will not extensible or clean. We always want to define a middleware as abstract or a separate file so that every middleware can perform a single type of responsibilities. For that purpose, we first create a class named MyMessageMiddleware which will display some text message before and after execution.

public class MyMessageMiddleware
{
 private readonly RequestDelegate _next;

 public MyMessageMiddleware (RequestDelegate next)
 {
 _next = next;
 }

 public async Task InvokeAsync(HttpContext context)
 {
 await context.Response.WriteAsync("!! Start of Custom Middleware !!\n\r");

 await _next(context);

 await context.Response.WriteAsync("\n\r!! End of Custom Middleware !!\");
 }
}

In the above class, we use the next RequestDelegate by the help of dependency injection as a part of the constructor. Also, we define a method named InvokeAsync which is as per the convention and we pass HttpContext as parameter to this function. Also, we pass the HttpContext to execute the next delegate call.

CREATING A MIDDLEWARE PIPLELINE

Now, we need to create an extension method of IApplicationBuilder to define the custom middleware pipleline.

public static class MyMessageMiddlewareExtensions
{
 public static IApplicationBuilder UseMyMessageMiddleware(this IApplicationBuilder builder)
 {
 return builder.UseMiddleware<MyMessageMiddleware>();
 }
}

Now, implement this custom middleware extension method in the Startup class:

public class Startup
{
 public void ConfigureServices(IServiceCollection services)
 {
 }

 public void Configure(IApplicationBuilder application, IHostingEnvironment appEnv)
 {
 application.UseMyMessageMiddleware ();

 app.Run(async (context) =>
 {
 await context.Response.WriteAsync("Beginning to Middleware…");
 });
 }
}
SUMMERY

So in this article, we discuss about the concept of Middleware, why it is required in .net core application, how we can configure it and also how we can create custom middleware for our applications. So, we need to remember the key points related to the middleware:

  • Middleware actually represents a group of classes which forms a queue or pipeline for handling request or response.

  • The mentioned pipeline will be end at the first execution of app.Run().

  • We want to use multiple middleware, then we can use app.Use()

  • We can create extension methods of IApplicationBuilder to include custom middleware in our application.

Hands-on Learning
+