I get a third-party API response which has several nested properties:
Variation 1:
{
"Property1": {
"Property2A": {
"Key1": "1",
"Key2": "2",
"Key3": "3"
},
"Property2B": {
"Property3": {
"Key4": "A",
"Key5": "B",
"Key6": "C",
"Property4": {
"Property5": {
"Property6": [
{
"Key7": "1",
"Property7A": {
"X": "1"
},
"Property7B": {
"X": "2"
},
"Property7C": {
"X": "3"
}
},
{
"Property7D": {
"X": "INeedThisString"
}
}
]
}
}
}
}
}
}
I only need the value "INeedThisString".
I am able to reach the value of property "X": "INeedThisString"
by a suitable model structure (generated by mapping the model over the Json-File) and with the following declarations:
Rootobject obj = JsonConvert.DeserializeObject<Rootobject>(MyJsonString);
string result = obj.Property1.Property2B.Property3.Property4.Property5.Property6[1].Property7D.X;
Here's my problem:
The API sometimes issues a variation of this architecture which has -as the only difference- Property3 declared as an array such as:
Variation 2:
{
"Property1": {
"Property2A": {
"Key1": "1",
"Key2": "2",
"Key3": "3"
},
"Property2B": {
"Property3": [ //<-----
{
"Key4": "A",
"Key5": "B",
"Key6": "C",
"Property4": {
"Property5": {
"Property6": [
{
"Key7": "1",
"Property7A": {
"X": "1"
},
"Property7B": {
"X": "2"
},
"Property7C": {
"X": "3"
}
},
{
"Property7D": {
"X": "INeedThisString"
}
}
]
}
}
}
] //<-----
}
}
}
//<-----
: added 2x for illustration purposes.
Obviously, variation 1 and my current model structure do not declare Property3
as an array.
Question:
What's an elegant approach to solve this without touching the Json (deletions/replacements) in pre-processing?
Should I implement an alternative set of models and switch between those two model-sets via an error-function? Please note that the keys within properties 7A
-7D
are all the same: "X"
.
CodePudding user response:
My current working solution covers an alternative set of classes needed for parsing, resulting from mapping Variant 2 of the Json response.
All classes are decorated by Json headers [JsonProperty("actual-string-shown-in-Json")] via using directive using Newtonsoft.Json
.
The two alternative JsonConvert
functions are placed within a try-catch statement:
string result;
try
{
Rootobject obj = JsonConvert.DeserializeObject<Rootobject>(MyJsonString);
result = obj.Property1.Property2B.Property3.Property4.Property5.Property6[1].Property7D.X;
}
catch
{
AltRootobject obj = JsonConvert.DeserializeObject<AltRootobject>(MyJsonString);
result = obj.AltProperty1.AltProperty.AltProperty[0].AltProperty.AltProperty5.AltProperty6[1].AltProperty7D.AltX;
}