What Is ASP.NET Core Middleware?
This is part N of ASP.NET Core tutorial. In this video, we'll understand what middleware is in ASP.NET Core. Middleware is a very broad term. In ASP.NET Core, middleware is a piece of software that can handle an HTTP request or response.
A given middleware component has a very specific purpose. For example, we may have a middleware component that authenticates a user, another piece of middleware to handle errors, yet another middleware to serve static files such as JavaScript files, CSS files, images, etc.
It is these middleware components that we use to set up a request processing pipeline. It is this pipeline that determines how a request is processed. The request pipeline is configured as part of the application startup by this Configure method that is present in the Startup class.
Configuring the Request Pipeline
We already know the execution of an ASP.NET Core project starts with this Main method. The Main method calls the CreateDefaultBuilder method which sets up a default web host. As part of setting up the web host, we are also configuring the Startup class using this UseStartup extension method, and this Startup class is present in this file. Within this class, we've got two methods: ConfigureServices and Configure. We'll discuss ConfigureServices in detail in our upcoming videos. In this video, let's discuss Configure. This is the method that sets up a request processing pipeline for our ASP.NET Core application.
The code in this method is generated by the empty project template. This code sets up a very simple request processing pipeline with just two pieces of middleware. The first middleware is this UseDeveloperExceptionPage, and the second middleware is registered using this Run extension method of this IApplicationBuilder interface. As it stands right now, with this very simple request processing pipeline, all our application can do is write a message to the response object, and that message will be displayed by the browser.
We'll come back and discuss the code that we have in this method in detail in our next video. For now, let's understand how middleware works in general in ASP.NET Core.
How Middleware Processes and Passes Requests
A middleware component in ASP.NET Core has access to both the incoming request and the outgoing response. So a middleware component may process an incoming request and then pass that request to the next piece of middleware in the pipeline for further processing.
For example, let's say logging middleware is the first middleware in our application request processing pipeline. So when a request arrives from the web server at this middleware, this middleware logs the time that the request is received and then passes that incoming request to the next piece of middleware, in our case to the static files middleware, for further processing.
Short-Circuiting the Request Pipeline
A middleware component may handle the incoming request and decide not to call the next piece of middleware in the pipeline. This is called short-circuiting the request pipeline. Short-circuiting is often desirable because it avoids unnecessary work.
For example, if the request is for a static file like an image, CSS file, JavaScript file, etc., this static files middleware can handle and serve that request and then short-circuit the rest of the pipeline. This means, in our case, the static files middleware will not call the next piece of middleware, that is the MVC middleware, if the request is for a static file like an image, for example.
The Full Request-Response Lifecycle
A middleware component may also simply ignore the incoming request and then pass that request on to the next piece of middleware for further processing. For example, let's say this time we are issuing a request to localhost/employees. Basically, we want to retrieve the list of all employees.
So when this request arrives from the web server at our first middleware in the pipeline, which is logging, this middleware simply logs the time the request is received and then passes that request to the next piece of middleware, in our case to static files middleware. Since this request is not for a static file like an image, CSS file, JavaScript file, etc., static files middleware may not be interested in processing this request. So it will simply pass that request to the next piece of middleware, which is MVC middleware.
This is an MVC request, so the MVC middleware knows how to handle that request. The respective MVC controller produces the HTTP response. At this point, the pipeline reverses itself. The MVC middleware passes that response to the static files middleware. The static files middleware is not interested in processing that response further, so it may simply pass that response to the next piece of middleware, which is the logging middleware. This middleware may simply log the time the response is received.
Remember, this logging middleware also has the time it received the request, so using these two times, it may also compute the overall time taken to service that request and then pass that response to the web server. The web server in turn may send that response to the client who made the request.
Middleware Configuration Principles
So it is these middleware components in the pipeline that determine how a request is processed in ASP.NET Core. These middleware components are executed in the order they are added to the pipeline. Care should be taken to add the middleware in the right order, otherwise the application may not function as expected. In our upcoming videos, we'll discuss with an example what happens if the middleware components are not added to the processing pipeline in the correct order.
These middleware components are available as NuGet packages. This means updates are now handled by NuGet, providing us the ability to update each middleware separately. Depending on your application requirements, you may add as many or as few middleware components to the request processing pipeline. For example, if you are developing a simple web application with a few static HTML pages and images, then your request processing pipeline may contain just this static files middleware. On the other hand, if you're developing a secure, data-driven web application, then you may need several middleware components like static files middleware, authentication middleware, authorization middleware, MVC middleware, etc.
The point that I'm trying to make is you have complete control over configuring the request processing pipeline. This also means from a memory and performance standpoint, you only pay for the middleware components you have in your application's request processing pipeline.
Summary and Next Steps
Now, let's quickly recap some of the important points to keep in mind as far as these middleware components are concerned.
Every middleware component in ASP.NET Core has access to both the incoming request and the outgoing response. A middleware component may simply pass the request to the next piece of middleware in the pipeline. A middleware component may do some processing and then pass that request on to the next piece of middleware for further processing. A middleware component may handle the request and short-circuit the rest of the pipeline. A middleware component may process the outgoing response as well. And finally, middleware is executed in the order they are added to the pipeline.
At this point, we have a basic understanding of what middleware components are and how they fit in a request processing pipeline. In our next video, we'll understand how to configure a request-processing pipeline for our ASP.NET Core application using these middleware components.
Thank you for watching.