Introduction
Middleware and the Request Pipeline are essential building blocks of ASP.NET Core that allow developers to control how HTTP requests and responses are handled within an application.
In this article, we’ll break down what middleware is and how the request pipeline works. Additionally, we’ll share a handy interview cheat sheet to boost your confidence during technical interviews.
What You’ll Learn in this article
-
The core concept of middleware and the request pipeline
-
The lifecycle of an HTTP request in ASP.NET Core
-
The use of
app.Use,app.Run, andapp.Map -
Built-in middleware components like static files, routing, authentication, Middleware ordering, and execution flow
-
How to write custom middleware with
RequestDelegateandHttpContext -
Difference between middleware and filters
-
Common interview questions and answers
What is Middleware?
In ASP.NET Core, middleware is a software component that is assembled into the application pipeline to handle HTTP requests and responses. Each middleware has the ability to:
-
Inspect the incoming request
-
Take action (e.g., logging, authentication)
-
Modify the request or response
-
Decide whether to pass the request to the next middleware or stop processing.
Middleware is added to the application in a specific order, and this order defines the flow of the HTTP request through the application.
What is the Request Pipeline?
The Request Pipeline is the sequence of middleware components that an HTTP request passes through on its way to a response. When a request hits the application:
-
Request enters the request pipeline.
-
Each middleware has a chance to:
-
Do something before passing it to the next component.
-
Do something after the next component has processed it.
-
-
The last component generates a response, which then flows back through the pipeline in reverse order.
How does it work?
-
Request enters the pipeline.
-
It goes through each middleware component in the order in which they are registered.
-
Each middleware can:
-
Do something before passing the request to the next middleware.
-
Do something after the next middleware has processed the request (usually on the response).
-
Short-circuit the pipeline by not calling the next middleware.
-
-
Finally, the response flows back through the pipeline.
Request → Middleware1 → Middleware2 → Middleware3 → Endpoint
↑ ↑ ↑ ↓
Do Something Do Something Do Something Generate response
Real-world scenario
Think of middleware as a series of layers in an onion. The HTTP request passes through each layer going in (toward the core), and the response comes back out through those same layers.
Lifecycle of an HTTP request
The lifecycle of an HTTP request in ASP.NET Core is a structured flow that begins when a request is received by the server and ends when the response is sent back to the client. Understanding this lifecycle helps you write better middleware, manage performance, and debug effectively.
Step-by-Step Lifecycle
1. Request Received by Kestrel
-
Kestrelis ASP.NET Core's cross-platform web server. -
It handles the low-level HTTP protocol and listens for requests.
2. Passed to Middleware Pipeline
-
ASP.NET Core uses a middleware-based pipeline.
-
Each middleware has a chance to:
-
Inspect or modify the request
-
Pass it to the next middleware (
await _next(context)) -
Stop the pipeline and return a response directly
-
3. Routing Middleware (app.UseRouting())
-
Parses the URL and determines which endpoint (controller, Razor Page, or minimal API) to use.
4. Authentication & Authorization (if configured)
-
Middleware like
UseAuthentication()andUseAuthorization()validate credentials and permissions.
5. Endpoint Execution
-
Executes the matched endpoint handler:
-
Controller Action (MVC/Web API)
-
Razor Page Handler
-
Minimal API method
-
SignalR hub method
-
-
This is where your app logic runs (database queries, business logic, etc.)
6. Response Travels Back Through Middleware
-
After the endpoint is processed, the response is sent back through the pipeline.
-
Middleware can now modify or log the response (e.g., logging, compression, headers).
7. Kestrel Sends Response to Client
-
The final HTTP response is sent back over the network to the client (browser, app, etc.)
| Client ↓ Kestrel Web Server ↓ Middleware Pipeline (UseMiddleware) ↓ Routing Middleware ↓ Endpoint Execution (Controller / Razor / Minimal API) ↓ Middleware Pipeline (Response flows back) ↓ Kestrel sends response ↓ Client |
| Lifecycle of an HTTP request |
| Component | Role |
|---|---|
| Kestrel | Handles HTTP connection |
| Middleware pipeline | Adds cross-cutting behavior (logging, auth, etc.) |
| Routing | Matches incoming request to endpoint |
| Endpoint execution | Runs controller, Razor page, or API logic |
| Response middleware | Can modify/log response before it leaves the server |
| Kestrel sends response | Final response goes back to the client |
app.Use – Middleware with next delegate
Adds middleware to the pipeline that will run for every request.
It doesn’t end the request instead, it passes control to the next middleware using await next.Invoke().
// Use Middleware: This runs for all requests
app.Use(async (context, next) =>
{
// Do something before
await next.Invoke(); // Call the next middleware
// Do something after
});
app.Map – Branching middleware
Used to branch the pipeline based on request paths.
This middleware will only be executed if the request path matches the specified path.
app.Map("/about", appBuilder =>
{
appBuilder.Run(async context =>
{
await context.Response.WriteAsync("About Page");
});
});
app.Run – Terminal middleware
This middleware will always execute if no previous middleware short-circuits the pipeline and does not call any next middleware.
It is typically used at the end of the pipeline to generate a final response and stop further processing.
app.Run(async context =>
{
await context.Response.WriteAsync("Hello from app.Run!");
});
Built-in middleware components in Asp.NET Core
Middleware components are pieces of code that are assembled into an application pipeline to handle requests and responses. ASP.NET Core provides several built-in middleware components to support common scenarios such as serving static files, handling authentication, routing requests, and more.
| Middleware | Description |
|---|---|
Static Files (UseStaticFiles) |
Serves static files like HTML, CSS, JS, images, etc., from the wwwroot folder. |
Routing (UseRouting) |
Matches the incoming HTTP requests to endpoints defined in the app. Required for endpoint routing. |
Endpoints (UseEndpoints) |
Executes the matched endpoint (e.g., controller action, Razor Page, minimal API). |
Authentication (UseAuthentication) |
Enables authentication logic (e.g., JWT, cookies, identity). Should be placed before authorization. |
Authorization (UseAuthorization) |
Validates that the user is authorized to access certain resources. |
CORS (UseCors) |
Enables Cross-Origin Resource Sharing (CORS) support to allow or restrict cross-origin requests. |
Exception Handling (UseExceptionHandler, UseDeveloperExceptionPage) |
Handles exceptions globally and provides error responses. Dev page shows detailed errors. |
HTTPS Redirection (UseHttpsRedirection) |
Redirects all HTTP requests to HTTPS. |
Session (UseSession) |
Enables session state in web apps. Requires session services configuration. |
Cookie Policy (UseCookiePolicy) |
Enables GDPR-compliant cookie handling, like consent checks. |
WebSockets (UseWebSockets) |
Enables WebSocket support for real-time communication. |
Response Caching (UseResponseCaching) |
Caches HTTP responses to improve performance. |
Middleware Pipeline in Program.cs
var builder = WebApplication.CreateBuilder(args);
// Add services
builder.Services.AddRouting();
builder.Services.AddAuthentication();
builder.Services.AddAuthorization();
builder.Services.AddControllersWithViews();
var app = builder.Build();
// Middleware pipeline
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.Run();
Key Points
The order in which middleware components are added is critical. For example:
-
UseRouting()→ beforeUseAuthorization() -
UseAuthentication()→ beforeUseAuthorization() -
UseStaticFiles()→ before routing so static content is served without hitting the MVC pipeline.
Custom Middleware
Creating custom middleware in ASP.NET Core allows you to insert your own logic into the HTTP request pipeline. This is useful for tasks like logging, custom authentication, modifying responses, or intercepting requests.
Step-by-step
-
Create the Middleware Class
-
Create an Extension Method
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
using System;
public class RequestLoggingMiddleware
{
private readonly RequestDelegate _next;
public RequestLoggingMiddleware(RequestDelegate next)
{
_next = next;
}
// Middleware logic
public async Task InvokeAsync(HttpContext context)
{
// Log the incoming request
Console.WriteLine($"[Request] {context.Request.Method} {context.Request.Path}");
await _next(context); // Call the next middleware
// Log the outgoing response
Console.WriteLine($"[Response] {context.Response.StatusCode}");
}
}
// Extension method for clean registration
public static class RequestLoggingMiddlewareExtensions
{
public static IApplicationBuilder UseRequestLogging(this IApplicationBuilder builder)
{
return builder.UseMiddleware<RequestLoggingMiddleware>();
}
}
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.UseHttpsRedirection();
// Register your custom middleware
app.UseMiddleware<RequestLoggingMiddleware>();
app.UseRouting();
app.UseAuthorization();
app.MapControllers();
app.Run();
Here are common interview questions and answers based on the topic “Mastering Middleware in ASP.NET Core: The Complete Guide to Request Pipeline”, suitable for .NET developer interviews:
🔹1. What is middleware in ASP.NET Core?
Answer
Middleware is software that's assembled into an application pipeline to handle requests and responses. Each component in the pipeline can either:
-
Handle the request completely, or
-
Pass it to the next middleware using
await next().
🔹 2. How is middleware registered in the request pipeline?
Answer
Middleware is registered in the Program.cs or Startup.cs using extension methods like app.Use, app.Run, and app.Map.
Example
app.UseMiddleware<CustomMiddleware>();
🔹 3. What's the difference between app.Use, app.Run, and app.Map?
| Method | Description |
|---|---|
Use |
Adds middleware that can call the next component. |
Run |
Terminates the pipeline; no further middleware is invoked. |
Map |
Branches the pipeline based on request path. |
Common interview questions and answers
1. What is middleware in ASP.NET Core?
Answer
Middleware is software that's assembled into an application pipeline to handle requests and responses. Each component in the pipeline can either:
-
Handle the request completely, or
-
Pass it to the next middleware using
await next().
2. How is middleware registered in the request pipeline?
Answer
Middleware is registered in the Program.cs or Startup.cs using extension methods like app.Use, app.Run, and app.Map.
app.UseMiddleware<CustomMiddleware>();
3. What's the difference between app.Use, app.Run, and app.Map?
| Method | Description |
|---|---|
Use |
Adds middleware that can call the next component. |
Run |
Terminates the pipeline, no further middleware is invoked. |
Map |
Branches the pipeline based on request path. |
4. Explain the order of middleware execution. Why is it important?
Middleware executes in the order it's registered. The order matters because:
-
Early middleware (like logging, exception handling) can wrap later middleware.
-
Authentication should be registered before authorization.
-
app.UseRouting()should come beforeapp.UseAuthorization().
5. How do you write a custom middleware in ASP.NET Core?
public class CustomMiddleware
{
private readonly RequestDelegate _next;
public CustomMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
// Pre-processing logic
await _next(context); // Call next middleware
// Post-processing logic
}
}
Register it using
app.UseMiddleware<CustomMiddleware>();
6. What is the role of RequestDelegate in middleware?
RequestDelegate represents the next middleware in the pipeline. It is used to invoke the next component using:
await _next(context);
7. How do you implement global exception handling using middleware?
Create a middleware that wraps the pipeline in a try-catch block and returns a custom response on error.
Example
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
public ExceptionMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
// Log and handle error
context.Response.StatusCode = 500;
await context.Response.WriteAsync("Internal Server Error");
}
}
}
8. What are terminal and non-terminal middleware?
-
Terminal Middleware: Ends the request pipeline (e.g.,
app.Run(...)) -
Non-terminal Middleware: Calls
await next()to pass control to the next middleware (e.g.,app.Use(...))
9. How does middleware support dependency injection?
You can inject services into middleware through the constructor.
Example
public class LoggingMiddleware
{
private readonly ILogger<LoggingMiddleware> _logger;
public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger)
{
_logger = logger;
}
}
10. Can you explain a real-time scenario where middleware is useful?
- Authentication Middleware is used to validate tokens before requests reach controllers.
- Logging Middleware can log every incoming request and outgoing response for audit and debugging.
Middleware – Summary Notes
-
Definition: Middleware is a component in the HTTP request pipeline that can inspect, modify, or terminate HTTP requests and responses during processing.
-
Execution: Executes for every HTTP request, regardless of whether the target is MVC, Razor Pages, static files, or others.
-
Placement: Middleware is configured in
Startup.csorProgram.csusing methods like:-
app.Use(...)– to call the next middleware in the pipeline -
app.Run(...)– to end the pipeline -
app.Map(...)– to branch the pipeline based on request path
-
-
Use Cases
-
Logging
-
Authentication & Authorization
-
CORS (Cross-Origin Resource Sharing)
-
Exception Handling
-
Response Compression
-
Localization
-
Request/Response Inspection
-
Request Redirection and Modification
-
-
Granularity: Middleware works at a global application level, affecting all incoming and outgoing requests.
Conclusion
Middleware plays a critical role in handling cross-cutting concerns across the application in a centralized and consistent way. It enables developers to build reusable, modular components that simplify request/response processing.
Mastering how and when to use middleware is essential for building robust, scalable, and maintainable ASP.NET Core applications. By strategically placing and organizing middleware, you can ensure better performance, cleaner code architecture, and improved application security.
Thank you for taking the time to read this post. I hope it has provided you with a clear understanding of middleware in ASP.NET Core and empowered you to apply it effectively in real-world applications.
Keep learning, keep experimenting, and keep building robust and scalable web solutions with confidence.

Алмаз НизамовPosted Nov 20, 2025, 8:39 AM
You have two first and second common questions for interview in this page)