A Brief Introduction to ASP.NET Core Middleware

One of the many changes that came with ASP.NET Core is a completely new model for the request pipeline. It is great, though, because it allows complete customization of how requests are handled in your application and there is an out-of-the-box solution for basic applications. Simple needs are serviced if the requirements are simple and the pipeline can be as complex as the requirements warrant.

General Overview

The ASP.NET Core request middleware is more commonly known as middleware. Middleware is configured to handle requests in a sequenced matter, going from one component of middleware to another. At any time a component can return the request and not pass it along to the next component. When a request is returned, however, it passes back through each previous middleware component in the opposite order. So, the last component it passed through on the way in, is the first it must then pass back through on its way out.

Figure 1 – Middleware

There are several middleware components available for use in your applications that are available as part of the ASP.NET Core installation. This is a non-comprehensive list but includes some of the most common to handle standard application scenarios.

Table 1 – Common Middleware Components Included with ASP.NET Core

Type

Method

Description

DeveloperExceptionPage UseDeveloperExceptionPage() Provides a detailed exception page if the application is running in development mode.
DatabaseErrorPage UseDatabaseErrorPage() Provides a detailed instruction page if the application requires Entity Framework migrations to be ran with instructions on possible actions.
ExceptionHandler UseExceptionHandler() Allows you to redirect to a specific error page when unhandled exceptions are encountered. Will also log the exception and re-execute the request if the response has not been started.
HSTS UseHsts() Adds a header for the Strict-Transport Security header.
HTTPSRedirection UseHttpsRedirection() Redirects HTTP traffic to HTTPS.
StaticFiles UseStaticFiles() Returns static content such as HTML, JavaScript, images, CSS, etc that do not need to be executed on the server.
CookiePolicy UseCookiePolicy() Adds cookie policy validation to the application.
Authentication UseAuthentication() Adds identity functionality such as authentication and authorization.
MVC UseMvc() Adds MVC routing and serving functionality to the application.

Custom Middleware

The requirements for developing your own custom middleware components are surprisingly simple. First, the constructor of the middleware should accept a RequestDelegate argument. The middleware you are developing may require more such as the IHostingEnvironment or ILoggingFactory interfaces but at the bare minimum, the RequestDelegate is required. Second, a public asynchronous method that returns a Task object named Invoke. The invoke method should accept an HttpContext argument. The Invoke method should be sure to call the next component in the chain via the Next argument of the constructor but as for requirements, that is it. Let’s take a look at a quick example.

A Simple Implementation

Listing 1 – SampleMiddleware.cs

public class SampleMiddleware
{
    public SampleMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    private RequestDelegate _next = null;

    public async Task Invoke(HttpContext context)
    {
        int dayOfYear = DateTime.Now.DayOfYear;

        context.Response.Headers.Add("X-DayOfYear", new[] { dayOfYear.ToString() });

        await _next(context);
    }
}

This is everything that is required for a new middleware component. In the constructor, I am saving a reference to the next RequestDelegate so it is available later in the Invoke method. In the Invoke method, I am simply adding a new header to the response that will have the day of the year as the header value and then calling the _next request delegate.

Listing 2 – Startup.cs

app.UseMiddleware<SampleMiddleware>();

Add this line to the Configure method of the Startup.cs file.

Figure 2 – Results

Conclusion

The ASP.NET Core Middleware, or request pipeline, is wildly different than what we may be accustomed to in ASP.NET 4 but it does offer much greater control and is something we should happily embrace. It is not difficult to create our own pipeline components and in this post, we did just that however simple the example.

Leave a Reply

Your email address will not be published.