Let's take an example to create a custom middleware for error handling in .NET Core, follow the steps below. The middleware will capture unhandled exceptions, log them, and return a user-friendly error response to the client.

1. Create the Middleware Class

Middleware/ErrorHandlingMiddleware.cs

C#
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.Text.Json;
using System.Threading.Tasks;

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ILogger<ErrorHandlingMiddleware> _logger;

    public ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware> logger)
    {
        _next = next;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            // Pass the request to the next middleware in the pipeline
            await _next(context);
        }
        catch (Exception ex)
        {
            // Log the exception
            _logger.LogError(ex, "An unhandled exception occurred.");

            // Handle the exception and return a response
            await HandleExceptionAsync(context, ex);
        }
    }

    private Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = StatusCodes.Status500InternalServerError;

        var response = new
        {
            error = "An unexpected error occurred.",
            details = exception.Message // Avoid exposing detailed info in production
        };

        var jsonResponse = JsonSerializer.Serialize(response);

        return context.Response.WriteAsync(jsonResponse);
    }
}

2. Register Middleware in the HTTP Pipeline

In .NET Core, middleware is registered in the Program.cs file (or Startup.cs for older configurations). Add the custom middleware to the pipeline.

Program.cs

C#
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddLogging();
var app = builder.Build();
// Add the custom error-handling middleware
app.UseMiddleware<ErrorHandlingMiddleware>();
// Other middlewares (e.g., routing, authentication)
app.MapControllers();
app.Run();

3. Test the Middleware

Create a test endpoint that throws an exception to confirm the middleware handles errors correctly.

Controllers/TestController.cs

C#
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
    [HttpGet("trigger-error")]
    public IActionResult TriggerError()
    {
        // Simulate an error
        throw new InvalidOperationException("This is a test exception.");
    }
}

4. Run and Test

Start the application.

Navigate to /api/test/trigger-error.

Verify the response.

Check the logs to confirm the exception is logged.