What is Middleware in ASP.NET Core MVC:
Middleware is a fundamental component in ASP.NET Core's request processing pipeline. Understanding it is essential for customizing how HTTP requests and responses are handled in your application.
Middleware can process the request before
next()and process the response afternext()returns.
Easy formula
Request → Before → next() → Endpoint → After → Response
REQUEST ↓
Middleware
┌─────────────┐
│ BEFORE │
└──────┬──────┘
↓
next()
↓
Next Middleware
↓
Endpoint
↓
┌─────────────┐
│ AFTER │
└─────────────┘
RESPONSE ↑Each middleware component:
-
Receives the HTTP request.
-
Performs some processing.
-
Optionally calls the next middleware in the pipeline.
-
Optionally modifies the HTTP response.
Simple definition
Middleware is a piece of software that sits between the client request and the final response and can inspect, modify, or stop the request/response.
CreateBuilder()
↓
Configure Services
↓
builder.Build()
↓
Configure Middleware
↓
Map Endpoints
↓ app.Run()
CreateBuilder() creates a WebApplicationBuilder object.
Think of it as:
"Prepare everything required to build my ASP.NET Core application."
It automatically sets up many things for you:
WebApplicationBuilder
|
|-- Configuration
|-- Dependency Injection
|-- Logging
|-- Environment
|-- Web Server settings
|
↓
Build Application
ASP.NET Core Middleware — Short Explanation
1. Use() — Middleware that can continue
app.Use(async (context, next) =>
{
Console.WriteLine("Before");
await next();
Console.WriteLine("After");
});
Use() creates middleware.- It can execute code before and after the next middleware.
next() sends the request to the next middleware.
Remember: Use() → Continue
2. next() — Go to next middleware
await next();
Means:
"Execute the next middleware in the pipeline."
Without next():
Middleware 1
↓
STOP ❌
With next():
Middleware 1
↓
Middleware 2
↓
Endpoint
Remember: next() → Next
3. Run() — Terminal middleware
app.Run(async context =>
{
await context.Response.WriteAsync("Hello");
});
Run() is terminal middleware.- It does not call
next(). - Pipeline stops here.
M1 → M2 → Run()
↓
STOP
Remember: Run() → Stop
4. Map() — Branch the pipeline
app.Map("/admin", adminApp =>
{
adminApp.Run(async context =>
{
await context.Response.WriteAsync("Admin Area");
});
});
If URL is:
/admin
the request goes into this branch.
Request
↓
Map()
/ \
/admin Other
↓ ↓
Admin Main Pipeline
Remember: Map() → Branch
Middleware Purpose Mandatory? UseHttpsRedirection()HTTP → HTTPS ❌ No UseStaticFiles()CSS, JS, images ❌ No UseRouting()Routing ❌ Not always explicitly required in modern minimal hosting UseAuthentication()Identify logged-in user ❌ Only if authentication is used UseAuthorization()Check permissions ❌ Only if authorization is used MapControllerRoute()Map MVC controller routes ✅ Required for conventional MVC routing UseExceptionHandler()Global exception handling ❌ Recommended UseCors()Cross-origin requests ❌ Only if CORS is needed
Recommended Middleware Order
var app = builder.Build();
app.UseExceptionHandler("/Home/Error");
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
Flow
HTTP Request
↓
Exception Handling
↓
HTTPS Redirection
↓
Static Files
↓
Routing
↓
Authentication
↓
Authorization
↓
Controller / Action
↓
HTTP Response
Why this order?
Order Middleware Purpose 1 UseExceptionHandler()Catch errors 2 UseHttpsRedirection()Redirect HTTP → HTTPS 3 UseStaticFiles()Serve CSS/JS/images 4 UseRouting()Select endpoint 5 UseAuthentication()Identify user 6 UseAuthorization()Check permission 7 MapControllerRoute()Map MVC endpoint
Most important table
Method Meaning Continue? Use()Normal middleware ✅ Yes, using next() next()Go to next middleware ➡️ Yes Run()Terminal middleware ❌ No Map()Branch pipeline based on path 🔀 Branch
Think of it as a series of checkpoints:
Browser ↓ Middleware 1 ↓ Middleware 2 ↓ Middleware 3 ↓ Controller / Endpoint ↓ Middleware 3 ↓ Middleware 2 ↓ Middleware 1 ↓ Browser
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.Use(async (context, next) => { Console.WriteLine("M1 - Before"); await next(); Console.WriteLine("M1 - After"); }); app.Use(async (context, next) => { Console.WriteLine("M2 - Before"); await next(); Console.WriteLine("M2 - After"); }); app.Run(async context => { Console.WriteLine("Endpoint"); await context.Response.WriteAsync("Hello World"); });. Basic Middleware
For example:
app.Use(async (context, next) => { Console.WriteLine("Middleware 1 - Before"); await next(); Console.WriteLine("Middleware 1 - After"); });Here:
await next();means:
2. Middleware Order is VERY Important
Suppose we have:
app.Use(async (context, next) => { Console.WriteLine("A - Before"); await next(); Console.WriteLine("A - After"); }); app.Use(async (context, next) => { Console.WriteLine("B - Before"); await next(); Console.WriteLine("B - After"); }); app.Use(async (context, next) => { Console.WriteLine("C - Before"); await next(); Console.WriteLine("C - After"); });When a request comes:
Request ↓ A ↓ B ↓ C ↓ EndpointBut the response comes back in reverse:
Endpoint ↓ C ↓ B ↓ A ↓ ResponseTherefore the console output will be:
A - Before B - Before C - Before C - After B - After A - AfterPass the request to the next middleware in the pipeline.
3. Why does "After" execute in reverse?
Because of:
await next();For example:
app.Use(async (context, next) => { Console.WriteLine("A Before"); await next(); Console.WriteLine("A After"); });Execution doesn't finish at:
await next();Instead, it temporarily goes to the next middleware.
So:
A Before ↓ await next() ↓ B Before ↓ await next() ↓ C Before ↓ Endpoint ↓ C After ↓ B After ↓ A AfterThis is similar to a stack: the last middleware entered is the first one to finish.
4. Real ASP.NET Core Middleware Order
A typical application may have:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); var app = builder.Build(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();
The order matters.
Conceptually:
Browser ↓ HTTPS Redirection ↓ Static Files ↓ Routing ↓ Authentication ↓ Authorization ↓ Controller ↓ Response
5.
UseAuthentication()vsUseAuthorization()
This is a very important example of middleware ordering.
Usually:
app.UseAuthentication(); app.UseAuthorization();
Authentication asks:
Who are you?
Authorization asks:
Are you allowed to access this resource?
Therefore:
Authentication ↓ Who is the user? ↓ Authorization ↓ Is this user allowed?
You generally shouldn't put Authorization before Authentication.
6. Routing Order
Consider:
app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers();
Routing determines which endpoint matches the request.
For example:
GET /api/student/10
Routing determines:
StudentController ↓ GetStudent(10)
Then authentication/authorization can operate with the selected endpoint's metadata.
7.
Use()vsRun()
This is another important middleware concept.
Use()
Use()can call the next middleware:
app.Use(async (context, next) => { Console.WriteLine("Before"); await next(); Console.WriteLine("After"); });
Run()
Run()is terminal middleware.
app.Run(async context => { await context.Response.WriteAsync("Hello"); });
It doesn't have
next.
Therefore:
A ↓ B ↓ Run() ↓ STOP
8. Example of
Run()
app.Use(async (context, next) => { Console.WriteLine("Middleware 1"); await next(); }); app.Run(async context => { await context.Response.WriteAsync("Hello"); }); app.Use(async (context, next) => { Console.WriteLine("Middleware 3"); await next(); });
What happens?
Middleware 1 ↓ Run() ↓ Response
Middleware in ASP.NET Core Pipeline
The middleware pipeline is configured in Startup.cs (or Program.cs in .NET 6+).
For .NET Core 3.1/ASP.NET Core MVC:

0 Comments
POST Answer of Questions and ASK to Doubt