ASP .NET Core Middleware
ASP .NET Core Middleware is software integrated within the applications pipeline which can be used to handle the requests and responses. It is a piece of code that executes every request.
Usually, we have multiple middleware components in an application. Each component can:
Choose whether to pass the request to the next component in the pipeline.
Execute some logic before or after the next component in the pipeline.
Request delegates are used to create the HTTP pipeline and it handles each HTTP request. To configure request delegates, we use Run, Map and Use extension methods. We can create middleware using an in-line anonymous method (in-line middleware) or using a custom reusable class (custom middleware).
In the request pipeline, the application executes in the same order as they are in the code.
Once the HTTP request is received, the first middleware will inspect it. The first middleware will pass the request to the next middleware if it doesn't have any response to return or any exception to be thrown and so on. And it's important to note that the middleware execution is bidirectional. You can read more on the middleware execution order here.
Let's look into the default middleware code of the program.cs file.
1) DeveloperExceptionPage
As we know middleware is bi-directional, the middleware will be the first one to receive the request and the last to send back the response it is very important what we place at the beginning of the pipeline. The DeveloperExceptionPage middleware is placed at the top so that it handles the exception thrown by any of the subsequent middleware.
2) Database Error Page
It returns the database runtime errors.
3) Exception Handler
Exception Handler Middleware catches exceptions thrown in the following middleware in the production environment.
4) HSTS
It adds the Strict-Transport-Security header.
5) HTTPS
It redirects the HTTP requests to HTTPS.
6) Static Files
It returns the static files for the request that's in the wwwroot folder of the application which contains usually contains js, CSS files and images.
7) Cookie Policy
To adhere to the default cookie policy such as SameSite and Secure.
8) Routing
It matches the endpoint route. An endpoint is an object which contains the information which is needed to execute the request. The routing middleware matches the endpoint route first and then the endpoint is executed.
9) Authentication
It authenticates the user before they are allowed to access the secure endpoints/resources.
10) Authorization
It authorizes the user to access secure resources. An important point to note is that Authentication checks if the user is valid or not and Authorization checks if the user has access or not.
11) Session
It establishes and maintains the session state of the application.
12) MapRazorPages
It maps the razor page endpoints to the request pipeline.
Building Custom Middleware
We can build our custom middleware based on the requirements using the use() method provided by the IApplicationBuilder.
The use() method takes RequestDelegate as a parameter and returns a RequestDelegate. As we know, a RequestDelegate is used to build an HTTP request pipeline and handle it. All the information about the HTTP request will be within the HTTPContext which is passed as the parameter for the RequestDelegate. So, based on it the middleware will be able to inspect the request and generate a response.
Example code:
app.Use(async (context, next) =>
{
// Do work that can write to the Response.
await next.Invoke();
// Do logging or other work that doesn't write to the Response.
});
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from 2nd delegate.");
});