.NET Core: Decoding .NET Core Custom Middleware

.NET Core

Note. For basic details, Please refer previous article - Unraveling Middleware Decoding

What is Custom Middleware?

Custom middleware serves as a robust and adaptable tool, empowering developers to execute a wide number of tasks, including but not limited to authentication, logging, and error handling. Its strength lies in its modularity and reusability, providing a flexible mechanism to seamlessly integrate custom logic into the request processing pipeline of ASP.NET Core applications. This versatility enables developers to craft tailored solutions that meet the specific needs of their projects while maintaining a modular and reusable codebase.

var app = builder.Build();
 
app.UseMiddleware<FirstMiddleware>(Guid.NewGuid());   

app.UseAuthorization();

app.UseMiddleware<SecondMiddleware>(Guid.NewGuid());
///
/// MapControllers is called to map attribute routed controllers. 
/// In the following example: HomeController matches a set of URLs similar to what the default
/// conventional route {controller=Home}/{action=Index}/{id?} matches
///
app.MapControllers();            
app.Run();
///
/// The function won't be invoked because it's scheduled to run after the app.Run() method. 
/// The rule dictates that middleware must be added before calling app.Run().
///
app.UseMiddleware<LastMiddleware>(Guid.NewGuid());

Middleware Processing

FirstMiddleware 
*****************
Entry. ID-> 7de251c04f3446c59ed27f981c838a3c 30/11/2023 04:39:06.041

	|-----------------
	|SecondMiddleware 
	|-----------------
	|Entry. ID-> 449b6ca954174aec85d9b0324a29c417 30/11/2023 04:39:07.068

			 => Entry. Hi, I'm Endpoint my details are below,
			 MiddlewareCollections.Controllers.WeatherForecastController - `Get`
			 Time: 30/11/2023 04:39:08.093

	|Exit. ID-> 449b6ca954174aec85d9b0324a29c417 30/11/2023 04:39:08.110
	|-----------------

Exit. ID-> 7de251c04f3446c59ed27f981c838a3c 30/11/2023 04:39:08.114

Custom Middleware implementation

public static void Main(string[] args)
{
    var builder = WebApplication.CreateBuilder(args);

    // Add services to the container.

    builder.Services.AddControllers();
    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();

    var app = builder.Build();
     
    // Register in the pipeline before calling Run()
    app.UseMiddleware<FirstMiddleware>(Guid.NewGuid());   
    
    app.UseAuthorization();

    // Register in the pipeline before calling Run()
    app.UseMiddleware<SecondMiddleware>(Guid.NewGuid());

    ///
    /// MapControllers is called to map attribute routed controllers. 
    /// In the following example: HomeController matches a set of URLs similar to what the default
    /// conventional route {controller=Home}/{action=Index}/{id?} matches
    ///
    app.MapControllers();   
    
    app.Run();
    ///
    /// The function won't be invoked because it's scheduled to run after the app.Run() method. 
    /// The rule dictates that middleware must be added before calling app.Run().
    /// !!! Not registered in the pipeline
    ///
    app.UseMiddleware<LastMiddleware>(Guid.NewGuid());
}
/// !!! Must Need  of this RequestDelegate  DI 
// Inject RequestDelegate ->  for process an HTTP request.
public class FirstMiddleware(RequestDelegate next,Guid guid)
{
    private readonly RequestDelegate _next = next;

    /// !!! Must Need  
    public async Task Invoke(HttpContext context)
    {
        Debug.WriteLine(" FirstMiddleware ");
        Debug.WriteLine("*****************");

        Debug.WriteLine($"Entry. ID-> {guid:n} {DateTime.UtcNow:dd/MM/yyyy hh:mm:ss.fff}");
        
        Thread.Sleep(1000);

        // Call the next middleware in the pipeline
        await _next(context);
        
        Debug.WriteLine($"Exit. ID-> {guid:n} {DateTime.UtcNow:dd/MM/yyyy hh:mm:ss.fff}");
    }
}
  • FirstMiddleware is a class that implements the middleware logic. It takes a RequestDelegate in its constructor, representing the next middleware in the pipeline.
  • The InvokeAsync method is where you put your custom logic before and after calling the next middleware.
  • app.UseMiddleware<FirstMiddleware>(Guid.NewGuid()); It adds your custom middleware to the application's request pipeline.

Furthermore, we will shed light on the concept of short-circuiting within the middleware architecture. Short-circuiting is a powerful technique that allows us to interrupt the usual flow of middleware execution, providing an early response under specific conditions. This can be instrumental in optimizing performance, implementing specialized handling, or even enforcing certain policies.

Stay tuned