In .NET Core, middleware allows you to handle exceptions centrally instead of writing multiple try-catch blocks in every controller.
Step 1: Create Middleware Class
using Microsoft.AspNetCore.Http;
using System;
using System.Net;
using System.Threading.Tasks;
public class ExceptionMiddleware
{
private readonly RequestDelegate _next;
public ExceptionMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
try
{
await _next(httpContext); // Call next middleware or endpoint
}
catch (Exception ex)
{
await HandleExceptionAsync(httpContext, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
// Log the exception (you can integrate Serilog/NLog here)
Console.WriteLine($"Something went wrong: {exception.Message}");
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
return context.Response.WriteAsync(new
{
StatusCode = context.Response.StatusCode,
Message = "Internal Server Error. Please try again later.",
Detailed = exception.Message // Optional — remove in production
}.ToString());
}
}
Step 2: Register Middleware in Program.cs or Startup.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Register the middleware
app.UseMiddleware();
app.MapControllers();
app.Run();
Step 3: Test it
Create a sample controller that throws an exception.
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
[HttpGet("error")]
public IActionResult GetError()
{
throw new Exception("This is a test exception!");
}
}
Now, when you browse to: https://localhost:5001/api/test/error
You’ll get a JSON response like:
{
"StatusCode": 500,
"Message": "Internal Server Error. Please try again later.",
"Detailed": "This is a test exception!"
}
app.UseExceptionHandler("/error");