I'm trying to log error objects as JSON in my ASP.NET Core 9 Web API. I am following the wiki in the NLog documentation: Structured logging.
I have NLog.Web.AspNetCore v6.0.5 as a dependency. In program.cs, I am calling UseNLog off of the Host:
var builder = WebApplication.CreateBuilder(args);
// NLog: Setup NLog for Dependency injection
builder.Logging.ClearProviders();
builder.Host.UseNLog();
In my controller I have ILogger as a class variable:
private readonly ILogger<MyController> _logger;
and assign it the injected ILogger in the constructor:
public MyController
(
IConfiguration configuration,
ILogger<MyController> nlog,
IHttpClientFactory httpClientFactory
)
{
_configuration = configuration;
_logger = nlog;
_httpClientFactory = httpClientFactory;
}
In the logger call I am using the @ prefix (the controller uses an HttpClient service and passes back any error).
//
if (!result.IsSuccessStatusCode)
{
string respContent = await result.Content.ReadAsStringAsync();
var errorObject = JsonConvert.DeserializeObject<APIError>(respContent);
//
_logger.LogError("request error: {@errorObject}", errorObject);
//
}
nlog.config has the out-of-the-box layout:
<!-- File Target for own log messages with extra web details using some ASP.NET core renderers -->
<target xsi:type="File" name="ownFile-web" fileName="C:\Logs\client\web-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
But the log entry just outputs a call to ToString() on the APIError object instead of giving me the JSON representation:
2025-11-26 13:22:00.5577|0|ERROR|Client.Controllers.MyController|request error: "Client.Models.ErrorResponses.APIError"
What am I missing?
respContentas a string, don't deserialize it.AspNetCoreandExtensions.Loggingpackages, still callingToString()NLog.LogManager.GetCurrentClassLogger().Error("@errorObject", errorObject). SinceMicrosoft.Extension.Loggingcan intervene forIEnumerable-parameters (New behavior introduced with NET8 or NET9)