Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deserialize JSON (snake_case) to dynamic (PascalCase)?

This code works fine:

string json = @"{""MyProperty"" : ""bar""}";

var payload = JsonConvert.DeserializeObject<dynamic>(json);

string typedProperty = payload.MyProperty; //contains "bar"

Let's try to do the same with snake_case JSON. We add a SnakeCaseNamingStrategy which is actually a recommended way to handle snake_case.

_snakeSettings = new JsonSerializerSettings()
{
    ContractResolver = new UnderscorePropertyNamesContractResolver()
};

public class UnderscorePropertyNamesContractResolver : DefaultContractResolver
{
    public UnderscorePropertyNamesContractResolver()
    {
        NamingStrategy = new SnakeCaseNamingStrategy();
    }
}           

Then, apply the settings to the DeserializeObject call. In case of deserialization to a static type, those settings are successfully applied to snake_case JSON:

string snakeJson = @"{""my_property"" : ""bar""}";

var payload = JsonConvert.DeserializeObject<Payload>(snakeJson, _snakeSettings);

string typedProperty = payload.MyProperty; //contains "bar"

OK, switch the target type to dynamic:

var payload = JsonConvert.DeserializeObject<dynamic>(snakeJson, _snakeSettings);

string typedProperty = payload.MyProperty; //is null
string wrongProperty = payload.my_property; //is not null

As you see, _snakeSettings are ignored this time. I guess this is a bug. Does any workaround exist to do JSON (snake_case) -> dynamic (PascalCase) deserialization?

Environment:

<TargetFramework>netcoreapp1.1</TargetFramework>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
like image 444
Ilya Chumakov Avatar asked Oct 11 '17 05:10

Ilya Chumakov


1 Answers

When you call JsonConvert.DeserializeObject<dynamic> it acts the same way as JsonConvert.DeserializeObject<JObject>. JObject is not a real result of the deserialization, but some intermediate state of your data, It is closer to readers than to objects. E.g. it allows you to deserialize only part of a JSON
So seems like JsonConvert.DeserializeObject<dynamic> creates not a result object but a reach, functional reader for the JSON data. I suppose, that's why it shows you data as it was without any post processing

I suppose it's better to direct that question to a "Newtonsoft.Json" developers.

like image 189
ASpirin Avatar answered Nov 04 '22 21:11

ASpirin