Middleware is a component in the ASP.NET Core request pipeline. Each HTTP request passes through a chain of components that can inspect the request, change the response, supply a supporting feature, or produce a response themselves. If none produces a response, ASP.NET Core returns HTTP 404 Not Found. section 12.2.1
Configure the pipeline in Program.cs. For example, app.UseStaticFiles() enables files from wwwroot, while endpoint routing connects requests to application endpoints. Order matters: a component can use only features made available by components that have already processed the request. section 7.1.5 section 16.3.2
Choose a form that fits the job:
- Use app.Use with an async lambda for a small component. It receives an HttpContext for the request and response, plus a next function that forwards the request. section 12.4
- Use app.UseMiddleware<T>() for a reusable class. Its constructor receives a RequestDelegate; its Invoke method receives HttpContext and calls the delegate with that context to continue. A single instance handles requests, so Invoke must be thread-safe. section 12.4.1
Listing 12.6 Creating custom middleware in the Program.cs file in the Platform folder
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Use(async (context, next) => {
if (context.Request.Method == HttpMethods.Get
&& context.Request.Query["custom"] == "true") {
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("Custom Middleware \n");
}
await next();
});
app.MapGet("/", () => "Hello World!");
app.Run();
This Program.cs listing shows a GET-and-query-string check, response writing, and await next() in one small pipeline. section 12.4
Calling next does not finish a component's work. Code before it runs on the way in; code after it runs as the response returns. A component may instead withhold forwarding to short-circuit the pipeline. Check Response.HasStarted before changing a status code or header: once headers have been sent, those changes are no longer allowed. section 12.4.2 section 12.6
Add a result on the return path
Register a component whose body is `await next(); await context.Response.WriteAsync($"\nStatus Code: {context.Response.StatusCode}");`. A request to `/` reaches the endpoint first; on return, the component appends the resulting status code. This is useful when a response depends on what later components did. section 12.4.2
Middleware also supplies features to later components. Session middleware retrieves server-side session data and exposes it through HttpContext.Session; place consumers after UseSession(). Authentication middleware populates HttpContext.User from a sign-in cookie. Authorization middleware needs the selected endpoint and authenticated user, so its position relative to routing and authentication matters. section 16.3.2 section 39.2.5 section 39.3.2
Class-based components can receive configuration through the options pattern: register options with Services.Configure, then request IOptions<T> in the constructor. This keeps configuration separate from request-processing code. section 12.5.1









