So, I have some JSON I’m deserialising. Bear in mind I don’t have control of the data I’m getting; I just have to work with it as best I can.
It was going fairly well, until I ran into an issue where in an item ("z" below) can be two different types (see "z":[] and "z":{}) within the same item type (in the data I’m dealing with, things should be considered a Dictionary<string, FooType> after deserialisation…).
{
"things":{
"1":{
"x":123.45,
"y":678.90,
"z":{
"2":true
},
"a":[
1,
2
]
},
"2":{
"x":1414.23,
"y":5656.78,
"z":[
true
],
"a":[
3
]
}
}
}
I’m pretty sure this is an output bug (i.e. the source is producing "z":[true] when it should produce "z":{"0":true}) because this is how "z":[true] is to be interpreted later in the application. However, as I said, I don’t have control of the data, and the issue is unlikely to be fixed any time soon.
I’ve tried having a member variable for each, but the naming conflict (from using [DataContract(Name = “z”)]) causes an exception (unsurprisingly).
How can I read both types of "z" into a common FooType? (Or equivalent, such as two subclasses of a common FooParentType that somehow get applied only in the correct cases…)
EDIT: I’d prefer to achieve the desired result as part of the deserialisation process, without preprcossing the string (although if there are no other ways, I’ll go there, I guess…)
I’m using C#, Mono, JSON.NET, and using code like so (compilable version on pastebin):
string jsonString = "{\"things\":{\"1\":{\"x\":123.45,\"y\":678.9,\"z\":{\"2\":true},\"a\":[1,2]},\"2\":{\"x\":1414.23,\"y\":5656.78,\"z\":[true],\"a\":[3]}}}";
RootType rt = JsonConvert.DeserializeObject<RootType>(jsonString);
With classes:
[DataContract]
class RootType
{
[DataMember(IsRequired = true)]
public Dictionary<string, FooType> things { get; set; }
}
[DataContract]
class FooType
{
[DataMember(IsRequired = true)]
public double x { get; set; }
[DataMember(IsRequired = true)]
public double y { get; set; }
[DataMember(IsRequired = true)]
public List<int> a { get; set; }
// List<bool> zList and Dictionary<string, bool> zDict each only work for one case
// but not the other, and having both causes a naming conflict
}
I had a similar issue and simply ran the string through a string.replace function to “correct” the data prior to deserializing.