0

I am calling a webservice which returns the response in json in the following format.

{
  "parent": 
    {
      "child": {
        "key1": value1,
        "key2": value2
      }
    }  
}

The above reponse is when there is only one child in the parent. But when there are more than one child in parent, then the response is as shown:

{
  "parent": [
    {
      "child": {
        "key1": "value1",
        "key2": "value2"
      }
    },
    {

      "child": {
        "key1": "value1",
        "key2": "value2"
      }
    }
  ]
}

Thus when there are more than one child elements, the parent is a JArray and when there is only child element, the parent is JObject.

Now I am having difficulty in parsing the contents of the child elements dynamically as it throws error of index when it is JObject.

Can someone explain how we can parse the contents both during JObject and JArray.

Currently I am checking the parent tag as whether it is JObject/ JArray and correspondingly parsing, but it is a long and tedious process.

Is there any other method for the same.

Following is code that I am using now

if(jsonfile["parent"].getType() == "JObject")
{
   string value1 = (string)jsonfile["parent"]["child"]["key1"]
}
else
{
   string value1 = (string)jsonfile["parent"][0]["child"]["key1"];
}

Is there any other method where we can get value1 without checking whether parent is JObject or JArray?

Dipumon
  • 149
  • 2
  • 16
  • You tagged json.net, if you are indeed using it, it would be much easier to [deserialize](http://www.newtonsoft.com/json/help/html/DeserializeObject.htm) the json to an object and work with that. Also see this question: https://stackoverflow.com/questions/4535840/deserialize-json-object-into-dynamic-object-using-json-net – Esko Jul 14 '17 at 06:33
  • no childX property do not change. I have corrected the mistake. – Dipumon Jul 14 '17 at 06:47
  • Do you want to parse your JSON to c# class or ? – Bob Swager Jul 14 '17 at 06:56
  • I just need to get the data from the key1 and key2. I can use class also or directly parsing. – Dipumon Jul 14 '17 at 07:00

1 Answers1

0

You could introduce an extension method such as

public static class JsonExtensions
{
    public static IEnumerable<JToken> SingleOrArrayItems(this JToken source)
    {
        if (source == null || source.Type == JTokenType.Null)
            return Enumerable.Empty<JToken>();
        IEnumerable<JToken> arr = source as JArray;
        return arr ?? new[] { source };
    }
}

And then do:

var child = jsonfile["parent"].SingleOrArrayItems().FirstOrDefault();
var value1 = child == null ? null : child.SelectToken("child.key1");

Or you could use SelectTokens() with the JSONPath recursive descent operator .. taking the place of the optional array index:

var value1 = jsonfile.SelectTokens("parent..child.key1").FirstOrDefault();

Sample fiddle.

(Questions about how to handle this sort of polymorphic JSON show up quite often; see for instance How to handle both a single item and an array for the same property using JSON.net for a way to deserialize JSON like this to fixed POCO types.)

dbc
  • 104,963
  • 20
  • 228
  • 340