In this article I will explain middleware concepts as follows,
- What is middleware
- Middleware Order of execution
- Create middleware using IApplicationBuilder
- Run, Use and Map method
- Custom middleware
- 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.
- UseAuthentication();
- 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.
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.
- public class Startup {
- public Startup() {}
- public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
-
-
- app.Run(async (context) => {
- await context.Response.WriteAsync("Hello my first middleware");
- });
-
- }
- }
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,
- public class Startup {
- public Startup() {}
- public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
- app.Run(TestMiddleware);
- }
- private Task TestMiddleware(HttpContext context) {
- return context.Response.WriteAsync("Hello TestMiddleware");
- }
- }
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,
-
- app.Run(async (context) => {
- await context.Response.WriteAsync("Middleware 1");
- });
-
- app.Run(async (context) => {
- await context.Response.WriteAsync("Middleware 2");
- });
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.
- public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
- app.Use(async (context, next) => {
- await context.Response.WriteAsync("Middleware 1");
- await next();
- });
- app.Run(async (context) => {
- await context.Response.WriteAsync("Middleware 2");
- });
- }
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.
- public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
- app.Map("/maptest", HandleMapMethod);
- }
- private static void HandleMapMethod(IApplicationBuilder app) {
- app.Run(async context => {
- await context.Response.WriteAsync("Map method testing");
- });
- }
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.
- public class MyCustomMiddleware {
- private readonly RequestDelegate _next;
- public MyCustomMiddleware(RequestDelegate next) {
- _next = next;
- }
- public Task Invoke(HttpContext httpContext) {
-
- return _next(httpContext);
- }
- }
- public static class MyMiddlewareExtensions {
- public static IApplicationBuilder UseMyCustomMiddleware(this IApplicationBuilder builder) {
- return builder.UseMiddleware < MyCustomMiddleware > ();
- }
- }
then you need to add your custom middleware in configure method,
- public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
- app.UseMyCustomMiddleware();
- app.Run(async (context) => {
- await context.Response.WriteAsync("Hello World!");
- });
- }
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.