What is Middleware?
Middleware in ASP.NET Core is a software component that is executed on every HTTP request and response. Middleware components are chained together to form a request-processing pipeline.
Each middleware:
- Can perform operations before and after the next component in the pipeline
- Can short-circuit the pipeline (e.g., for authentication, error handling)
- Is executed in the order registered in the Program.cs
Middleware Examples
ASP.NET Core has built-in middleware such as:
- UseRouting() – for routing requests
- UseAuthentication() – for checking identity
- UseAuthorization() – for permission control
- UseEndpoints() – for mapping controllers
Middleware executes in the order added — request goes top to bottom, response goes bottom to top.
Request Pipeline Flow
Here’s how a typical request moves through middleware:
Request
↓
[Middleware 1] → [Middleware 2] → ... → [Middleware N] → Controller
↑ ↑
Response ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ← ←
- Do something before passing the request forward
- Do something after the next middleware has completed
How to Create a Custom Middleware.
Step 1: Create a class with a constructor accepting RequestDelegate
Step 2: Add InvokeAsync(HttpContext) method
Step 3: Call _next(context) inside the method
Step 4: Register it using app.UseMiddleware<YourMiddleware>()
Step 1: Create a Middleware Class
public class LoggingMiddleware { private readonly RequestDelegate _next; private readonly ILogger<LoggingMiddleware> _logger; public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { _logger.LogInformation($"Incoming request: {context.Request.Method} {context.Request.Path}"); await _next(context); _logger.LogInformation($"Response: {context.Response.StatusCode}"); } }
Step 2: To keep Program.cs clean, create extension methods for your middleware.
public static class MiddlewareExtensions { public static IApplicationBuilder UseLoggingMiddleware(this IApplicationBuilder app) { return app.UseMiddleware<LoggingMiddleware>(); } }
var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.UseLoggingMiddleware(); // 👈 From your extension method app.UseRouting(); app.UseAuthorization(); app.MapControllers(); app.Run();
📁 Recommended Middleware File Structure.
/YourProjectRoot
│
├── Program.cs
├── Startup.cs (if applicable)
│
├── Middleware/
│ ├── LoggingMiddleware.cs
│ ├── ExceptionHandlingMiddleware.cs
│ └── RequestTimingMiddleware.cs
│
└── Extensions/
└── MiddlewareExtensions.cs
When to Use Custom Middleware?
You might create custom middleware to:
- Log requests and responses
- Handle exceptions globally
- Modify headers
- Implement custom authentication or IP filtering
- Measure performance/response time
Typical Middleware Order in Program.cs
Here is the recommended and logical order of middleware in most real-world ASP.NET Core applications:
var app = builder.Build(); app.UseExceptionHandler("/error"); // 1. Global exception handling app.UseHsts(); // 2. Enforce HTTPS strict transport (in production) app.UseHttpsRedirection(); // 3. Redirect HTTP to HTTPS app.UseStaticFiles(); // 4. Serve static files (JS, CSS, images) app.UseRouting(); // 5. Enable routing system app.UseCors(); // 6. Enable CORS if needed app.UseAuthentication(); // 7. Identity/authentication check app.UseAuthorization(); // 8. Role-based or policy-based authorization app.UseMiddleware<CustomLoggingMiddleware>(); // 9. Your custom middlewares app.UseEndpoints(endpoints => // 10. Connects routes to controllers { endpoints.MapControllers(); }); app.Run();
Common Middleware Interview Question.
Q1. What is the difference between Use, Run, and Map?
- Use: Adds middleware to the pipeline, can call next
- Run: Terminal middleware, doesn't call next
- Map: Branches pipeline based on request path
Q2. Can a middleware return a response without calling the next middleware?
Answer Tip: Yes. This is called short-circuiting. For example, authentication or CORS middleware might return a response early.
Q3. What happens if you don't call _next(context) in a middleware?
Answer Tip: The pipeline is terminated, and the request doesn't reach subsequent middleware or the controller.
Q4. How do you handle exceptions globally in middleware?
Answer: Use a custom exception-handling middleware or app.UseExceptionHandler().
No comments:
Post a Comment