Search code examples
c#json.nethttprequesthttpresponse.net-6.0

C# .NET Core 6 HttpRequest convert to json for logging?


I am using .NET Core 6 and I'm looking to convert the request and response to JSON for logging. When I use Newtonsoft.Json to convert the object I am getting an out of memory exception. What is the simplest and or best way to convert it without having to go through field by field?

Exception I got when trying to simply convert it.

Code of my logging middleware

public class RequestResponseLoggerMiddleware
{
    private readonly RequestDelegate _next;
    private readonly AppSettings _appSettings;
    private readonly ILogger<RequestResponseLoggerMiddleware> logger;

    public RequestResponseLoggerMiddleware(
        RequestDelegate next,
        IOptions<AppSettings> appSettings,
        ILogger<RequestResponseLoggerMiddleware> logger)
    {
        _next = next;
        _appSettings = appSettings.Value;
        this.logger = logger;
    }

    public async Task Invoke(HttpContext context)
    {
        logger.LogInformation($"{JsonConvert.SerializeObject(context.Request, Formatting.None, new JsonSerializerSettings(){ReferenceLoopHandling = ReferenceLoopHandling.Ignore})}");

        await _next(context);

        logger.LogInformation($"{JsonConvert.SerializeObject(context.Response, Formatting.None, new JsonSerializerSettings(){ReferenceLoopHandling = ReferenceLoopHandling.Ignore})}");
    }
}

Error:

Something went wrong: System.OutOfMemoryException: Insufficient memory to continue the execution of the program.

at System.Text.StringBuilder.ExpandByABlock(Int32 minBlockCharCount)
at System.Text.StringBuilder.Append(Char* value, Int32 valueCount)
at System.Text.StringBuilder.AppendHelper(String value)
at System.IO.StringWriter.Write(String value)
at Newtonsoft.Json.JsonWriter.AutoCompleteClose(JsonContainerType type)
at Newtonsoft.Json.JsonWriter.WriteEnd(JsonContainerType type)
at Newtonsoft.Json.JsonWriter.WriteEnd()
at Newtonsoft.Json.JsonWriter.AutoCompleteAll()
at Newtonsoft.Json.JsonWriter.Close()
at Newtonsoft.Json.JsonTextWriter.Close()
at Newtonsoft.Json.JsonWriter.Dispose(Boolean disposing)
at Newtonsoft.Json.JsonWriter.System.IDisposable.Dispose()
at Newtonsoft.Json.JsonConvert.SerializeObjectInternal(Object value, Type type, JsonSerializer jsonSerializer)
at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Type type, Formatting formatting, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.SerializeObject(Object value, Formatting formatting, JsonSerializerSettings settings)
at API.Middleware.RequestResponseLoggerMiddleware.Invoke(HttpContext context)

What is the suggested / better way to do this?


Solution

  • Another option:

    According to Microsoft documentation in .Net 6 you can log request and response by adding app.UseHttpLogging(); middleware.

    HTTP Logging is a middleware that logs information about HTTP requests and HTTP responses. HTTP logging provides logs of:

    • HTTP request information
    • Common properties
    • Headers
    • Body
    • HTTP response information

    HTTP Logging is valuable in several scenarios to:

    • Record information about incoming requests and responses.
    • Filter which parts of the request and response are logged.
    • Filtering which headers to log.