最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - How to configure serilog to destructure objects to JSON using camelCase property naming policy instead of default PascalCas

programmeradmin7浏览0评论

I'm currently working on an ASP.NET Core 8 Web API. I have already configured the application to serialize and deserialize JSON messages to and from controller endpoints with JsonNamingPolicy.CamelCase using .AddControllers(...).AddJsonOptions().

I use a simple text file sink with messages, and Serilog configuration is the standard used for a Web API.

When I try to log the object after a successful deserialization, just inside the controller methods, the Serilog destructurer serializes the object to JSON in PascalCase, as in the original case of the object class model.

How do I apply JsonNamingPolicy.CamelCase to Serilog configuration/destructurer?

Example of json sent to my API:

{
    "textField": "value", "uselessField": "value2"
}

My API deserializes to input model object:

public class Input
{
    public string TextField { get; set; }  
}

I log the input object after deserialization with this line

_logger.LogDebug("API RECEIVED {@InputModel}"}, input);

The log message part is written as:

API RECEIVED {"TextProp":"value"}

but I need camelCase format:

API RECEIVED {"textProp":"value"}

Is there a possible solution?

The JSON library used is System.Text.Json.

I'm currently working on an ASP.NET Core 8 Web API. I have already configured the application to serialize and deserialize JSON messages to and from controller endpoints with JsonNamingPolicy.CamelCase using .AddControllers(...).AddJsonOptions().

I use a simple text file sink with messages, and Serilog configuration is the standard used for a Web API.

When I try to log the object after a successful deserialization, just inside the controller methods, the Serilog destructurer serializes the object to JSON in PascalCase, as in the original case of the object class model.

How do I apply JsonNamingPolicy.CamelCase to Serilog configuration/destructurer?

Example of json sent to my API:

{
    "textField": "value", "uselessField": "value2"
}

My API deserializes to input model object:

public class Input
{
    public string TextField { get; set; }  
}

I log the input object after deserialization with this line

_logger.LogDebug("API RECEIVED {@InputModel}"}, input);

The log message part is written as:

API RECEIVED {"TextProp":"value"}

but I need camelCase format:

API RECEIVED {"textProp":"value"}

Is there a possible solution?

The JSON library used is System.Text.Json.

Share Improve this question edited Mar 19 at 8:05 Ruben Bartelink 61.9k32 gold badges194 silver badges262 bronze badges asked Mar 18 at 22:33 albealbe 1511 gold badge2 silver badges12 bronze badges 2
  • 1 Why do you care? – mjwills Commented Mar 18 at 23:32
  • it's to check if deserialization missed some fields in case the subcontractor made some errors in their calls composition. We have tons of fields in the models but if all properties are deserialized with the wrong case i can't compare in a fast way the HTTP body and the deserialized object. This api is being integrated and called by tons of different clients and i have to check often, despite out swagger is 1:1 on out models. – albe Commented Mar 18 at 23:39
Add a comment  | 

1 Answer 1

Reset to default 2

You can create a custom CamelCase policy to implement this feature.

Test Code

[HttpPost]
public IActionResult Post([FromBody] InputModel input)
{
    _logger.LogDebug("API RECEIVED {@InputModel}", input);
    return Ok();
}

Test Result

Here is the details.

CamelCaseDestructuringPolicy.cs

using Serilog.Core;
using Serilog.Events;
using System.Text.Json;

namespace _79518749
{
    public class CamelCaseDestructuringPolicy : IDestructuringPolicy
    {
        public bool TryDestructure(
            object value,
            ILogEventPropertyValueFactory propertyValueFactory,
            out LogEventPropertyValue? result)
        {
            var options = new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                WriteIndented = false
            };

            try
            {
                var json = JsonSerializer.Serialize(value, options);
                var dict = JsonSerializer.Deserialize<Dictionary<string, object>>(json, options);
                var properties = dict.Select(kv =>
                    new LogEventProperty(kv.Key, new ScalarValue(kv.Value)));

                result = new StructureValue(properties);
                return true;
            }
            catch
            {
                result = null;
                return false;
            }
        }
    }
}

Program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .Destructure.With<CamelCaseDestructuringPolicy>() 
    .WriteTo.Console()
    .CreateLogger();

builder.Host.UseSerilog(); 

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
    });

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();
...

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论