Middleware is the term used for the components that are combined to form the request pipeline. This pipeline is arranged like a chain. The request is either returned by the middleware or passed to the next one until a response is sent back. Once a response is created, the response will travel the chain back, passing all middlewares again, which allows them to modify this response.
It may not be intuitive at first, but this allows for a lot of flexibility in the way the parts of an application are combined.
You can find the source code of the following demo on GitHub.
Creating a Content-Generating Middleware
A middleware can be a pretty simple class since it doesn’t implement an interface and doesn’t derive from a base class. Instead, the constructor takes a RequestDelegate object and defines an Invoke method. The RequestDelegate links to the next middleware in the chain and the Invoke method is called when the ASP.NET application receives an HTTP request. All the information of the HTTP requests and responses are provided through the HttpContext in the Invoke method.
On the following screenshot, you can see a simple implementation of a middleware which returns a string if the request path is /contentmiddleware
The request pipeline or chain of middlewares is created in the Configure method of the Startup class. All you have to do is app.UseMiddleware<MyMiddleware>(); A request is only passed through a middleware when it is registered in the Startup class.
That’s already everything you have to do to use the middleware. Start the application and enter /contentmiddleware and you will see the response from the middleware.
Creating a Short-Circuiting Middleware
A short-circuiting middleware intercepts the request before the content generating components (for example a controller) is reached. The main reason for doing this is performance. This type of middleware is called short-circuiting because it doesn’t always forward the request to the next component in the chain. For example if your application only allows Chrome users, the middleware can check the client agent and if it is not Chrome, a response with an error message is created.
It is important to note that middlewares are called in the same order as they are registered in the Startup class. The middleware which is registered first will handle the request first. Short-circuiting middlewares should always be placed at the front of the chain.
If you make a request from Chrome (also from Edge since it is using Chromium now), you will see the access denied message.
Calls with a different browser, for example, Firefox still create a response.
Creating a Request-Editing Middleware
A request-editing middleware changes the requests before it reaches other components but doesn’t create a response. This can be used to prepare the request for easier processing later or for enriching the request with platform-specific features. The following example shows a middleware which sets a context item if the browser used is Edge.
Creating a Response-Editing Middleware
Since there is a request-editing middleware, it won’t be surprising that there is also a response-editing middleware which changes the response before it is sent to the user. This type of middleware is often used for logging or handling errors.
Now register the middleware in your Startup class. It may not be intuitive but it is important that a response-editing middleware is registered first because the response passes all middlewares in the reverse order of the request. This means that the first middleware processes the request first and the response last.
If you start your application and enter an URL which your system doesn’t know (and don’t use Chrome), you will see your custom error text.
In this post, I talked about middlewares. I explained what they are and what different types there are.