I’m trying to convert JSON responses, in which all keys are in snake_case, for example
{
"op": 0,
"t": "some_name",
"d": {
"heartbeat_interval": 10000,
"user": {
"user_id": 1
}
}
}
(This is just one of the many things that d
could be)
and this would need to be converted to a c# class, such as:
class Example {
public int op { get; set; }
public string t { get; set; }
public dynamic d { get; set; } // What's in this cannot be predicted
}
Which could then be accessed using res.d.user.userId
or res.d.heartbeatInterval
for example.
I know this is possible with serialising camelCase TO snake_case but I can’t find any way to do it the other way around
I’ve tried looking on the newtonsoft documentation but I couldn’t find anything except from converting camelCase TO snake_case.
2
Answers
Consider using [JsonProperty] attribute, it will indicate the name of the property you want to deserialize from.
Alternatively you could omit using [JsonProperty] attribute and use Newtonsoft’s SnakeCaseNamingStrategy class in JsonSerializerSettings when deserializing.
When you declare a member to be of type
object
ordynamic
, Json.NET will deserialize JSON objects and arrays as eitherJObject
orJArray
from the LINQ to JSON document object model. Since their base typeJToken
implementsIDynamicMetaObjectProvider
, you are able to query these types using dynamic syntax such asres.d.user.userId
.Now, there is no built-in way to automatically rename properties as they are being loaded into a
JToken
hierarchy, but you could adopt some of the code from this answer to Get a dynamic object for JsonConvert.DeserializeObject making properties uppercase to create a custom converter that does this:Next, modify
Example
as follows:And you will be able to deserialize your JSON and perform dynamic queries using camel case as required:
Notes:
The
SnakeToCamelCase()
method is merely a prototype that removes all underscores and uppercases any character that had been preceded by an underscore.If you would prefer smarter handling for property names with leading and trailing underscores, or sequences of multiple underscores (e.g.
"_property_name__0001_"
or"___"
or whatever) modify the method to your tastes.It’s possible you could get get name collisions when remapping from snake case, e.g.:
The code above detects this situation and throws a
JsonException
. If you don’t want that you can remove the check fromRenamingJTokenWriter.WritePropertyName()
, but if you do, the deserialized object will contain the value of the final duplicate name encountered.Demo fiddle here.