Understand the building blocks of request processing in ASP.NET Core.
In ASP.NET Core, middleware is software that's assembled into an application pipeline to handle requests and responses. Each piece of middleware has the ability to:
This pipeline model provides a flexible and extensible way to build web applications. You can think of it as a series of components that a request passes through on its way to the server and on its way back to the client.
The ASP.NET Core middleware pipeline is configured in the Startup.cs
file (or Program.cs
in .NET 6+) within the Configure
method.
The order in which middleware components are added to the pipeline is crucial, as it determines the order in which they are executed. The pipeline is executed in the order of registration for incoming requests, and in the reverse order for outgoing responses.
// Example in Startup.cs (older .NET Core versions)
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllers();
});
}
// Example in Program.cs (.NET 6+)
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
UseDeveloperExceptionPage
: Displays detailed error information in development environments.UseHttpsRedirection
: Redirects HTTP requests to HTTPS.UseStaticFiles
: Serves static files (HTML, CSS, JavaScript, images).UseRouting
: Enables routing to select the correct endpoint.UseAuthentication
: Authenticates the user.UseAuthorization
: Authorizes the user to access resources.UseEndpoints
: Configures endpoint mapping for the application.You can create your own custom middleware to add specific functionality to your request pipeline.
This is the most common and recommended approach.
public class MyCustomMiddleware
{
private readonly RequestDelegate _next;
public MyCustomMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
// Do something before the next middleware
Console.WriteLine("Request entering custom middleware...");
await _next(context); // Call the next middleware in the pipeline
// Do something after the next middleware has run (response processing)
Console.WriteLine("Request exiting custom middleware...");
}
}
// In Startup.Configure or Program.cs
app.UseMiddleware<MyCustomMiddleware>();
Extension methods make it easier to add custom middleware to the pipeline.
public static class MiddlewareExtensions
{
public static IApplicationBuilder UseMyCustomMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyCustomMiddleware>();
}
}
// In Startup.Configure or Program.cs
app.UseMyCustomMiddleware();
The sequence in which middleware is invoked is critical. For example, UseRouting
must be called before UseAuthorization
so that the authorization middleware knows which endpoint to authorize against.
Consider the following common ordering:
UseDeveloperExceptionPage
, UseExceptionHandler
)UseHttpsRedirection
)UseStaticFiles
)UseRouting
UseAuthentication
)UseAuthorization
)UseEndpoints
or MapRazorPages
, MapControllers
)Task InvokeAsync(HttpContext context)
builds the pipeline.