I have a JSON file formatted like so, which is generated by a tool that I cannot edit:
{
"thing_name1": {
"property1": 0,
"property2": "sure"
},
"thing_name2": {
"property1": 34,
"property2": "absolutely"
}
}
The class I'm trying to deserialize to is as such:
[DataContract]
public class Thing
{
[DataMember]
public String ThingName;
[DataMember(Name="property1")]
public int Property1;
[DataMember(Name="property2")]
public String Property2;
}
I need to put the values of "thing_name1" and "thing_name2" into the ThingName data member of their respective deserialized objects, but haven't been able to find an easy way to do this without writing a custom (de)serializer. Or writing a quick Python script to write another file, but that wouldn't be very space efficient.
Yes, this is possible, but you do need some custom code to do it.
It's a little ugly, but you can create a custom
IDataContractSurrogate
class to deserialize the JSON into aDictionary<string, Dictionary<string, object>>
, and then copy the values from the nested dictionary structure into aList<Thing>
. Here's the code you would need for the surrogate:To use the surrogate, you'll need to create an instance of
DataContractJsonSerializerSettings
and pass it to theDataContractJsonSerializer
with the following properties set. Note that since we require theUseSimpleDictionaryFormat
setting, this solution will only work with .Net 4.5 or later.Note that in your
Thing
class you should NOT mark theThingName
member with a[DataMember]
attribute, since it is handled specially in the surrogate. Also, I made the assumption that your class members are actually properties (with{ get; set; }
) and not fields like you wrote in your question. If that assumption is incorrect, you'll need to change all the references toPropertyInfo
in the surrogate code to useFieldInfo
instead; otherwise the surrogate will not work.Here is a round-trip demo:
Output: