Global Error Handling in ASP.NET Core Web API using NLog

Introduction

Implementing global error handling in an ASP.NET Core Web API using NLog involves setting up a custom middleware to catch and log exceptions that occur during the request pipeline. NLog is a popular logging framework for .NET that provides flexible and powerful logging capabilities. Here’s how you can implement global error handling using NLog in an ASP.NET Core Web API:

Step 1: Install NLog and NLog.Web.AspNetCore

In your ASP.NET Core Web API project, install the NLog and NLog.Web.AspNetCore NuGet packages:

dotnet add package NLog
dotnet add package NLog.Web.AspNetCore

Step 2: Configure NLog

Create an nlog.config file in the root directory of your project with the following configuration:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Info"
      internalLogFile="internal-nlog.txt">

  <targets>
    <target xsi:type="File" name="allfile" fileName="nlog-all.log"
            layout="${longdate}|${event-properties:item=EventId_Id}|${logger}|${uppercase:${level}}|${message} ${exception}" />
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="allfile" />
  </rules>
</nlog>

This configuration will log all events to the nlog-all.log file.

Step 3: Create Custom Exception Middleware

Create a new class for your custom exception middleware, such as GlobalExceptionMiddleware.cs:

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using NLog;

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

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

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An unhandled exception occurred.");
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
        }
    }
}

Step 4: Register Custom Middleware and NLog in Startup.cs

In the Startup.cs file, configure the custom exception middleware and NLog:

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NLog.Extensions.Logging;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddLogging(loggingBuilder =>
        {
            loggingBuilder.ClearProviders();
            loggingBuilder.AddNLog();
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        // ...

        app.UseMiddleware<GlobalExceptionMiddleware>();

        // ...
    }
}

Step 5: Test Global Error Handling

In your controllers, you can throw exceptions to test the global error handling and logging. For example:

using Microsoft.AspNetCore.Mvc;
using System;

[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
    [HttpGet("throw")]
    public IActionResult ThrowException()
    {
        throw new ApplicationException("This is a test exception.");
    }
}

Step 6: Run the Application and Check Logs

Run your ASP.NET Core Web API and make requests to the TestController endpoint /api/test/throw. Check the nlog-all.log file to see the logged exceptions.

In summary, implementing global error handling using NLog in an ASP.NET Core Web API involves creating a custom exception middleware and configuring NLog. This allows you to catch and log unhandled exceptions that occur during the request pipeline. Proper error handling and logging are essential for diagnosing and resolving issues in your application.

Leave a Reply

Your email address will not be published. Required fields are marked *