Kris Harper
Kris Harper

Reputation: 5872

How can I serialize ExpandoObjects using snake_case with Json.NET?

I'm trying to serialize ExpandoObjects to JSON with Json.NET using snake_case property names. It seems as though the contract resolver isn't working as expected.

For example

dynamic test = new ExpandoObject();
test.TestProperty = "Value";
JsonSerializer serializer = new JsonSerializer();
serializer.ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() };
JObject result = JObject.FromObject(test, serializer);
string resultStr = result.ToString(); // { "TestProperty": "Value" }

If I change

serializer.ContractResolver = new DefaultContractResolver { NamingStrategy = new SnakeCaseNamingStrategy() };

to

serializer.ContractResolver = new CamelCasePropertyNamesContractResolver();

then I get the expected camelCase results.

Also if I change the ExpandoObject to something like

class Test
{
    public string TestProperty { get; set; }
}

Test test = new Test { TestProperty = "Value" };

then I get the expected { "test_property": "Value" }.

This is ultimately part of a JsonConverter class, so I can't extract this code too much. It needs to eventually write json to a JsonWriter instance.

Upvotes: 0

Views: 1170

Answers (1)

dbc
dbc

Reputation: 117344

You need to set NamingStrategy.ProcessDictionaryKeys = true:

serializer.ContractResolver = new DefaultContractResolver 
{ 
    NamingStrategy = new SnakeCaseNamingStrategy { ProcessDictionaryKeys = true } 
};

(This works because ExpandoObject implements IDictionary<String,Object> and Json.NET serializes it as such. Json.NET does have a custom converter for deserialization of ExpandoObject, however the converter returns CanWrite = false causing Json.NET to fall back on generic dictionary serialization code.)

Demo fiddle here.

Upvotes: 2

Related Questions