C#

Understanding Middleware in .NET Core

In .NET core when we make any HTTP request to server it goes with multiple building blocks of code called Middleware.



The ASP.NET Core request pipeline consists of a sequence of request delegates, called one after the other.

Middleware in .NET Core is a component that is executed in the request pipeline to handle HTTP requests and responses. It plays a crucial role in processing requests before they reach the application’s core logic and modifying responses before sending them back to the client. Middleware components can perform operations such as authentication, logging, exception handling, request transformation, and response modification.


Example:

Suppose we want to authenticate HTTP request before reaching to Server then we can add code logic to authenticate in request pipeline then we can call that logic as Middleware.

Another example:

Suppose we want to Add some header to each response for request and code logic that will perform to add headers to response is called middleware.


How Middleware Works in .NET Core

Middleware follows a pipeline pattern where multiple middleware components execute sequentially. Each middleware can:

1. Process the request and decide whether to pass it to the next middleware.

2. Process the response before returning it to the client.

Middleware Execution Flow

1. A request comes in.

2. The first middleware processes it and passes it to the next middleware.

3. Each middleware in the pipeline processes the request.

4. The last middleware in the chain processes the request and generates a response.

5. The response moves back through the middleware pipeline, where each middleware can modify it before sending it to the client.




Use Cases of Middleware in .NET Core

Middleware is used for:

1. Logging requests and responses.
2.Exception handling.
3. Authentication and authorization.
4.Response compression.
4.CORS (Cross-Origin Resource Sharing) handling.
5. Request and response modification.
6.Rate limiting.
7. Custom business logic execution at the request level.

Built-in Middleware in .NET Core


1. UseRouting() : Determines the request route.
2. UseAuthentication() : Handles authentication.
3. UseAuthorization() : Handles authorization.
4. UseCors() : Manages CORS policies.
5. UseStaticFiles() : Serves static files.
6. UseExceptionHandler() : Handles global exceptions.
7. UseEndpoints(): Maps routes to endpoints.

Example

var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); app.Run();

Middleware Execution Order

Middleware execution order is critical because:

1. The request flows down through the pipeline.
2. The response flows up through the pipeline.


app.Use(async (context, next) => { Console.WriteLine("Middleware 1: Before Request"); await next(); Console.WriteLine("Middleware 1: After Response"); }); app.Use(async (context, next) => { Console.WriteLine("Middleware 2: Before Request"); await next(); Console.WriteLine("Middleware 2: After Response"); }); app.Run(async context => { Console.WriteLine("Middleware 3: Request Processed"); await context.Response.WriteAsync("Final Response"); });

Output


Middleware 1: Before Request Middleware 2: Before Request Middleware 3: Request Processed Middleware 2: After Response Middleware 1: After Response

Understanding app.Use() and app.Run() in .NET Core
In .NET Core, middleware components are added to the request pipeline using methods like app.Use() and app.Run(). These methods determine how HTTP requests are processed.

app.Use() is used to register middleware that can either:

1. Pass the request to the next middleware.
2. Short-circuit the pipeline and handle the request directly.
3. It provides an optional next delegate, allowing the request to continue down the pipeline.


var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.Use(async (context, next) => { Console.WriteLine("Middleware 1: Before Next()"); await next(); // Passes control to the next middleware Console.WriteLine("Middleware 1: After Next()"); }); app.Use(async (context, next) => { Console.WriteLine("Middleware 2: Before Next()"); await next(); Console.WriteLine("Middleware 2: After Next()"); }); app.Run(async context => { Console.WriteLine("Middleware 3: Handling Request"); await context.Response.WriteAsync("Final Response"); }); app.Run();

Execution Flow


Middleware 1: Before Next() Middleware 2: Before Next() Middleware 3: Handling Request Middleware 2: After Next() Middleware 1: After Next()

Key Points
1. app.Use() middleware must call next() if it wants the request to continue to the next middleware.
2. If next() is not called, the pipeline stops there.

How to use app.Run()

1. app.Run() is a terminal middleware, meaning it handles the request and does not pass it further.
2. It is usually used for simple request handling.


Example

var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.Run(async context => { await context.Response.WriteAsync("Hello from `app.Run()`!"); }); app.Run();

When to Use app.Use() vs. app.Run()
1. app.Use() : When you want to execute logic before and after passing control to the next middleware.
2. app.Run() : When you want to terminate the pipeline and send a response immediately.


Happy coding and happy learning

line

Copyrights © 2024 letsupdateskills All rights reserved