MSDN Documentation

Understanding ASP.NET Core Middleware

Middleware is a component that is part of the ASP.NET Core request pipeline. Each piece of middleware is responsible for performing a specific task on an incoming HTTP request or an outgoing HTTP response. Middleware components can be chained together to form the request pipeline, allowing for a modular and composable approach to handling web requests.

The Request Pipeline

In ASP.NET Core, incoming HTTP requests are processed by a sequence of middleware components. This sequence is often referred to as the "request pipeline." Each middleware component has the opportunity to:

Core Concepts of Middleware

A middleware component typically has a single responsibility. Common examples include:

How Middleware Works

Each middleware component receives an instance of HttpContext, which encapsulates information about the current HTTP request and response. The pipeline is constructed using an extension method, UseMiddleware<T>, or by implementing the IMiddleware interface.

The Invoke or InvokeAsync Method

A middleware component's primary method is typically named Invoke or InvokeAsync. This method accepts the HttpContext and a delegate representing the rest of the pipeline. The middleware can then choose to call this delegate to pass the request to the next component.

Consider a simple logging middleware:

public class LoggingMiddleware
{
    private readonly RequestDelegate _next;

    public LoggingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        Console.WriteLine($"Request received: {context.Request.Path}");

        // Call the next middleware in the pipeline
        await _next(context);

        Console.WriteLine($"Response sent for: {context.Request.Path}");
    }
}

// In Startup.cs or Program.cs
// app.UseMiddleware<LoggingMiddleware>();

Order Matters

The order in which middleware components are added to the pipeline is crucial. Middleware components are executed in the order they are registered. For example, an authentication middleware should typically run before an authorization middleware, and both should run before MVC or Razor Pages handlers.

Key Takeaway: The request pipeline is a sequence of components, each performing a specific action. The order of these components dictates how requests are processed.

Built-in Middleware

ASP.NET Core provides a rich set of built-in middleware components that you can easily integrate into your application:

Custom Middleware

You can create your own custom middleware to encapsulate specific logic. This promotes code reusability and separation of concerns.

Implementing IMiddleware

An alternative way to create middleware is by implementing the IMiddleware interface. This approach offers better testability and dependency injection support.

public class CustomHeaderMiddleware : IMiddleware
{
    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        context.Response.Headers.Add("X-Custom-Header", "MyValue");
        await next(context);
    }
}

// In Startup.cs or Program.cs
// services.AddTransient<CustomHeaderMiddleware>();
// app.UseMiddleware<CustomHeaderMiddleware>();

Conclusion

Middleware is a fundamental concept in ASP.NET Core that provides a powerful and flexible way to build web applications. By understanding how the request pipeline works and how to create and configure middleware, developers can build robust, performant, and maintainable applications.