<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nazib Mahfuz</title>
    <description>The latest articles on DEV Community by Nazib Mahfuz (@mahfuznazib).</description>
    <link>https://dev.to/mahfuznazib</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1049478%2Fcac8b66c-ed0c-4303-9f24-abb5333b988c.jpeg</url>
      <title>DEV Community: Nazib Mahfuz</title>
      <link>https://dev.to/mahfuznazib</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mahfuznazib"/>
    <language>en</language>
    <item>
      <title>Custom Middleware in ASP.NET Core</title>
      <dc:creator>Nazib Mahfuz</dc:creator>
      <pubDate>Mon, 04 Aug 2025 04:51:55 +0000</pubDate>
      <link>https://dev.to/mahfuznazib/custom-middleware-in-aspnet-core-4hm7</link>
      <guid>https://dev.to/mahfuznazib/custom-middleware-in-aspnet-core-4hm7</guid>
      <description>&lt;p&gt;Middleware manages requests and responses in a modular, pipeline-based manner. It processes HTTP requests and can execute actions before forwarding the request to the next middleware or returning a response to the client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Middleware Works?&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkg1ezml5amk4iuspufz9.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkg1ezml5amk4iuspufz9.webp" alt=" " width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This diagram illustrates how middleware operates in an .NET Core application pipeline. Let’s break down each component:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTTP Request&lt;/strong&gt;: An incoming HTTP request enters the application and moves through each middleware in the pipeline’s defined order.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Middleware 1, Middleware 2, and Middleware 3:&lt;/strong&gt; These are various middleware components, each executing specific logic as the request progresses through the pipeline.&lt;br&gt;
&lt;strong&gt;Logic Before&lt;/strong&gt;: Each middleware has a “Logic Before” section to perform actions or checks before passing the request further. Tasks may include logging, authentication, or request modification.&lt;br&gt;
&lt;strong&gt;next():&lt;/strong&gt; After completing “Logic Before” actions, each middleware calls next() to forward the request to the next middleware.&lt;br&gt;
&lt;strong&gt;Logic After:&lt;/strong&gt; Once the response is generated and begins its return journey up the pipeline, each middleware can execute additional actions in the “Logic After” section, typically for logging or modifying the response before it exits the application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Application Logic (e.g., an API Controller):&lt;/strong&gt; After traversing all middleware, the request reaches the application logic (such as a controller), which processes the request and generates a response.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTTP Response:&lt;/strong&gt; The generated response travels back up the pipeline, passing through each middleware again in reverse order, allowing the execution of each middleware’s “Logic After” section. Finally, the response exits the application and is sent to the client.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  N
&lt;/h2&gt;

&lt;p&gt;ow let’s create a custom middleware in ASP.NET Core that logs the request time for each HTTP request.&lt;/p&gt;

&lt;p&gt;We create a middleware class called RequestLoggingMiddleware&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RequestLoggingMiddleware.cs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class RequestLoggingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger&amp;lt;RequestLoggingMiddleware&amp;gt; _logger;

    public RequestLoggingMiddleware(RequestDelegate next, ILogger&amp;lt;RequestLoggingMiddleware&amp;gt; logger)
    {
        _next = next;
        _logger = logger;
    }

    // This InvokeAsync method handle the HttpContext
    public async Task InvokeAsync(HttpContext context)
    {
        // Log the incoming request
        _logger.LogInformation($"Handling Request. HttpMethod : {context.Request.Method} || Http Path: {context.Request.Path}");
        var stopwatch = Stopwatch.StartNew();

        // Call the next middleware in the pipeline
        await _next(context);   

        stopwatch.Stop();
        _logger.LogInformation($"Finished Handling Request. Request Processing time : {stopwatch.ElapsedMilliseconds} ms");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Constructor&lt;/strong&gt;: Accepts a RequestDelegate for the next middleware in the pipeline and an ILogger to log messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;InvokeAsync&lt;/strong&gt;: This method handles the request. It logs the HTTP method and path at the beginning, then starts a stopwatch to track processing time. After calling the next middleware with _next(context), it stops the stopwatch and logs the elapsed time.&lt;br&gt;
To make it easier to add our middleware to the pipeline, create an extension method.&lt;/p&gt;

&lt;p&gt;Here is our &lt;code&gt;RequestLoggingMiddlewareExtensions.cs&lt;/code&gt; class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static class RequestLoggingMiddlewareExtensions
{
    public static IApplicationBuilder UseRequestLogging(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware&amp;lt;RequestLoggingMiddleware&amp;gt;(); // Use our custom middleware name
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This static method extends &lt;code&gt;IApplicationBuilder&lt;/code&gt; by adding a custom &lt;code&gt;UseRequestLogging&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;It calls &lt;code&gt;UseMiddleware&amp;lt;RequestLoggingMiddleware&amp;gt;()&lt;/code&gt;, which registers &lt;code&gt;RequestLoggingMiddleware&lt;/code&gt; in the middleware pipeline.&lt;/p&gt;

&lt;p&gt;This allows the middleware to be added in the Startup class with a simple call to &lt;code&gt;app.UseRequestLogging()&lt;/code&gt;.&lt;br&gt;
And now for logging our information, we install &lt;code&gt;SeriLog&lt;/code&gt; NuGet package. From NuGet package manager install this 3 packages&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Serilog&lt;/li&gt;
&lt;li&gt;Serilog.Extensions.Hosting&lt;/li&gt;
&lt;li&gt;Serilog.Sinks.File&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After installing the necessary packages, now we can register our custom middleware in our Program class. Here is the code&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Program.cs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        // Configure Serilog for file logging
        builder.Host.UseSerilog((context, config) =&amp;gt;
        {
            config.WriteTo.File("Logs/log.txt", rollingInterval: RollingInterval.Day);
        });

        // Add services to the container.
        builder.Services.AddControllers();
        builder.Services.AddLogging();
        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen();

        var app = builder.Build();
        app.UseRequestLogging();  // ***** Add Our Custom Middleware ****//

        // Configure the HTTP request pipeline.
        if (app.Environment.IsDevelopment())
        {
            app.UseSwagger();
            app.UseSwaggerUI();
        }

        app.UseHttpsRedirection();
        app.UseAuthorization();
        app.MapControllers();

        app.Run();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In here by adding this code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Configure Serilog for file logging
builder.Host.UseSerilog((context, config) =&amp;gt;
{
    config.WriteTo.File("Logs/log.txt", rollingInterval: RollingInterval.Day);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we configure our logging file. And for register our custom middleware we do like this &lt;code&gt;app.UseRequestLogging();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now if we run our Web API, we can see the logging of each request.&lt;/p&gt;

&lt;p&gt;Now we also can create our custom middleware for specific API endpoints. Again we create a another custom middleware called &lt;code&gt;EmployeeActivationleware&lt;/code&gt; for only employee routes. For simplicity in this middleware we just add some log information. There was no logic inside this middleware.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class EmployeeActivationMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger&amp;lt;EmployeeActivationMiddleware&amp;gt; _logger;

    public EmployeeActivationMiddleware(RequestDelegate next, ILogger&amp;lt;EmployeeActivationMiddleware&amp;gt; logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // Write the actual code logic here
        _logger.LogInformation($"Date &amp;amp; Time : {DateTime.Now.ToString()}: Employee Activation Middleware for specific Controller");
        await _next(context);
        // Write logic here [if any]
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can directly register this middleware for any specific routes. Here we will use this middleware for &lt;code&gt;/api/Employee&lt;/code&gt; routes. Then we can register it in our &lt;code&gt;Program&lt;/code&gt; class like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Map Middleware for Specific Routes
app.UseWhen(context =&amp;gt; context.Request.Path.StartsWithSegments("/api/Employee"), appBuilder =&amp;gt;
{
    appBuilder.UseMiddleware&amp;lt;EmployeeActivationMiddleware&amp;gt;();
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will works fine. But we can use extension method for this. If we want to do that again we will create another extension class called &lt;code&gt;EmployeeActivationMiddlewareExtensions&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static class EmployeeActivationMiddlewareExtensions
{
    public static IApplicationBuilder UseEmployeeActivationForEmployeeRoutes(this IApplicationBuilder builder)
    {
        return builder.UseWhen(
            context =&amp;gt; context.Request.Path.StartsWithSegments("/api/Employee"),
            appBuilder =&amp;gt; appBuilder.UseMiddleware&amp;lt;EmployeeActivationMiddleware&amp;gt;()
        );
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can just use this middleware like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var app = builder.Build();
app.UseRequestLogging(); // This is for Request Logging
app.UseEmployeeActivationForEmployeeRoutes() // This is for Specific Routes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if we run our application, we can also see the log file with latest update&lt;/p&gt;

</description>
      <category>middleware</category>
      <category>dotnetcustommiddleware</category>
      <category>aspnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Global Exception Handling in ASP.NET Core</title>
      <dc:creator>Nazib Mahfuz</dc:creator>
      <pubDate>Thu, 31 Jul 2025 16:04:50 +0000</pubDate>
      <link>https://dev.to/mahfuznazib/global-exception-handling-in-aspnet-core-h8l</link>
      <guid>https://dev.to/mahfuznazib/global-exception-handling-in-aspnet-core-h8l</guid>
      <description>&lt;p&gt;Exception handling is a critical aspect of an ASP.NET application. While we often use try-catch blocks for this, we can streamline the process by implementing a global error handling mechanism.&lt;/p&gt;

&lt;p&gt;.NET 8 introduce a new feature called IExceptionHandler . This interface is under Microsoft.AspNetCore.Diagnostics namespace.&lt;/p&gt;

&lt;p&gt;What is IExceptionHandler ?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Centralized Exception Handling: We can handle all known exception in one place.&lt;/li&gt;
&lt;li&gt;Custom Logics: We can define how to handle different types of exceptions&lt;/li&gt;
&lt;li&gt;Control Processing: Handlers can return true to stop further processing or false to let other handlers take over.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s build a simple .NET application with an &lt;code&gt;EmployeeController&lt;/code&gt; and an &lt;br&gt;
&lt;code&gt;EmployeeModel&lt;/code&gt; to define a few basic properties.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class EmployeeModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string PhoneNo { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;EmployeeController&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace GlobalExceptionHandling.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeeController : ControllerBase
    {
        private readonly List&amp;lt;EmployeeModel&amp;gt; employees;

        public EmployeeController()
        {
            employees = new List&amp;lt;EmployeeModel&amp;gt;();
            employees.Add(new EmployeeModel { Id = 1001, Name = "Nazib Mahfuz", PhoneNo = "01777127618" });
            employees.Add(new EmployeeModel { Id = 1002, Name = "Kazi Malik", PhoneNo = "01777127618" });
            employees.Add(new EmployeeModel { Id = 1003, Name = "Ali Hasan Mito", PhoneNo = "01777127618" });
            employees.Add(new EmployeeModel { Id = 1004, Name = "Tahmid Hossain", PhoneNo = "01777127618" });
            employees.Add(new EmployeeModel { Id = 1005, Name = "Maksudul Islam Rahat", PhoneNo = "01777127618" });
            employees.Add(new EmployeeModel { Id = 1006, Name = "Millat Kanchan", PhoneNo = "01777127618" });
        }
        [HttpGet]
        [Route("GetAllEmployee")]
        public async Task&amp;lt;IActionResult&amp;gt; GetAllEmployees()
        {
            try
            {
                int totalEmployee = employees.Count();
                int perPage = totalEmployee / 0; // Force create exception
                return Ok(employees);
            }
            catch (Exception ex)
            {
                return BadRequest(ex.Message);
            }
        }


        [HttpGet]
        [Route("GetEmployeeByID")]
        public async Task&amp;lt;IActionResult&amp;gt; GetEmployeeByID()
        {
            try
            {
                var employee = employees.Find(x =&amp;gt; x.Id == 1009); 
                return Ok(employee);
            }
            catch (Exception ex)
            {
                return BadRequest(ex);
            }

        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we create an &lt;code&gt;EmployeeList&lt;/code&gt; and populate it with some dummy data. For simplicity, we define two API endpoints: &lt;code&gt;GetAllEmployee&lt;/code&gt; and &lt;code&gt;GetEmployeeByID&lt;/code&gt;. To handle exceptions, we use a try-catch block in each case. To handle the exception in one place we create a class called &lt;code&gt;AppExceptionHandler&lt;/code&gt; . This class must be inherit by &lt;code&gt;IExceptionHandler&lt;/code&gt; interfaces. Here is the implementation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Diagnostics;

namespace GlobalExceptionHandling
{
    public class AppExceptionHandler : IExceptionHandler
    {
        public ValueTask&amp;lt;bool&amp;gt; TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
        {
            return ValueTask.FromResult(true);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to implement the &lt;code&gt;TryHandleAsync&lt;/code&gt; method, which takes three parameters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;HttpContext: This represents the current HTTP request and response context. It provides access to request details such as headers, route data, and user information. We can use this parameter to retrieve data and modify our exception handling logic accordingly.&lt;/li&gt;
&lt;li&gt;Exception: This parameter contains details about the exception, including the error message, whenever an error occurs.&lt;/li&gt;
&lt;li&gt;CancellationToken: This special parameter indicates whether the async operation should be canceled. It’s used to handle cancellation requests from the user or system during the execution of an async task.
--&amp;gt; If a client disconnects or the server shuts down, the cancellation token notifies the handler to stop further processing.
--&amp;gt; By halting unnecessary operations, it helps conserve system resources such as memory and CPU.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Registering IExceptionHandler&lt;/strong&gt;&lt;br&gt;
Next, we need to register our global exception handler class in the program to ensure that any exceptions are caught and handled automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var builder = WebApplication.CreateBuilder(args);
builder.Services.AddExceptionHandler&amp;lt;AppExceptionHandler&amp;gt;();
app.UseExceptionHandler( _ =&amp;gt; { });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We register our AppExceptionHandler class using the line builder.Services.AddExceptionHandler(). Additionally, we need to add the middleware UseExceptionHandler() and pass a parameter.&lt;/p&gt;

&lt;p&gt;In this case, the _ symbol is a convention in C# to indicate that the parameter is unused, meaning we don't need to use the IApplicationBuilder object in our custom handler logic.&lt;/p&gt;

&lt;p&gt;The { } part represents the body of the lambda expression, where you can write the logic to handle exceptions globally.&lt;/p&gt;

&lt;p&gt;Now, we can create another class to display global exceptions in a formatted way. Here’s the class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class ExceptionResponse
{
    public int StatusCode { get; set; }
    public string Title { get; set; }
    public string ExceptionMessage { get; set; }
    public DateTime ExceptionDateTime { get; set; }
    public string StackTrace { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update &lt;code&gt;TryHandleAsync&lt;/code&gt;methods&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async ValueTask&amp;lt;bool&amp;gt; TryHandleAsync(HttpContext httpContext, Exception exception, CancellationToken cancellationToken)
{

    var exceptionResponse = new ExceptionResponse()
    {
        StatusCode = StatusCodes.Status500InternalServerError,
        Title = "Unexpected Error Occured",
        ExceptionMessage = exception.Message,
        ExceptionDateTime = DateTime.UtcNow, 
        StackTrace = exception.StackTrace ?? "No Stack Trace Found"
    };

    var jsonResponse = JsonSerializer.Serialize(exceptionResponse);

    httpContext.Response.StatusCode = exceptionResponse.StatusCode;
    httpContext.Response.ContentType = "application/json";

    await httpContext.Response.WriteAsync(jsonResponse);

    return true;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also retrieve the stack trace details. This means we no longer need to write a try-catch block in each method. We can refine our methods as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;EmployeeController.cs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[HttpGet]
[Route("GetAllEmployee")]
public async Task&amp;lt;IActionResult&amp;gt; GetAllEmployees()
{
    int totalEmployee = employees.Count();
    int perPage = totalEmployee / 0;
    return Ok(employees);
}


[HttpGet]
[Route("GetEmployeeByID")]
public async Task&amp;lt;IActionResult&amp;gt; GetEmployeeByID()
{
    var employee = employees.Find(x =&amp;gt; x.Id == 1009);
    return Ok(employee);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
The IExceptionHandler interface in .NET 8 simplifies centralized exception management. By implementing and registering custom exception handlers, you can ensure consistent and maintainable error handling across your application. This enhances the overall quality of your code and makes your application more robust.&lt;/p&gt;

</description>
      <category>globalexceptionhandling</category>
      <category>exceptionhandling</category>
      <category>aspnetcore</category>
    </item>
  </channel>
</rss>
