1

I am new to C# and JSON and need some help in getting the Key name(s) in a list of a nested JSON object. The keys are dynamic so I won't necessarily know the keys.

sample code I've tried.

```
protected void test()
{
        var mystring = @"{
          ""zone1"": {
            ""sites"": {
              ""site1"": {
                ""to"": ""email1"", 
                ""subject"": ""subjecttxt"", 
                ""link"": ""somesite""
            },
            ""site2"": {
              ""to"": ""email1"", 
              ""subject"": ""subject"",
              ""link"": ""somesite""
            }
          }, 
          ""zone2"": {
            ""to"": ""email1"", 
            ""subject"": ""subject"", 
            ""link"": ""somelink""
          }}";
        var rss = JObject.Parse(mystring);

        foreach (var section in rss)
        {
            Console.Write(section.Key);
            IList<JToken> result = rss["zone1"]["sites"].Children().ToList();
            var zone = section.Key;
            var site = rss[zone]["sites"];
            foreach (var subsite in rss["zone1"]["sites"])
            {
                var subs = subsite.Parent.ToString();
                // some other code
            }
         }
}
```

Looking for a result:

site1, site2, ...

I can get the children as IList but looking for something similar to "section.Key" as noted above.

Thank you for your help.

Mukesh Panchal
  • 1,956
  • 2
  • 18
  • 31
Kheel
  • 13
  • 1
  • 3

2 Answers2

3

I believe what you are looking for is to get the properties of the sites. Since accessing the rss["zone1"]["sites"] returns a JToken, you will need to convert that to JObject and then use Properties() method to get the data you need.

var sites = ((JObject)rss["zone1"]["sites"]).Properties();

Then you can simply iterate over the IEnumerable<Jproperty> to get the Name of the property or whatever else you need from under it.

To get the section.Key for the sites, you can use the following code.

foreach(var site in (JObject)rss["zone1"]["sites"]) {
    Console.WriteLine(site.Key);
}

Output:

site1
site2
Mukesh Panchal
  • 1,956
  • 2
  • 18
  • 31
Jawad
  • 11,028
  • 3
  • 24
  • 37
0

Your first call to JObject.Parse already does all the work of converting a string into a structured JSON object. The currently-accepted answer redoes some of this work by (1) turning a structured JSON object back into a string, and then (2) re-parsing it with JObject.Parse. There is a simpler way.

Instead, you can cast the value stored at rss["zone1"]["sites"] into a JObject. (The expression rss["zone1"]["sites"] has type JToken, which is a parent class of JObject, but in this case we happen to know that rss["zone1"]["sites"] is always JSON object, i.e. a collection of key-value pairs. Therefore, this cast is safe to perform.)

This is what the code might look like:

var sites = (JObject) rss["zone1"]["sites"];
foreach (var site in sites)
{
  Console.WriteLine(site.Key);
}
Nick
  • 1,038
  • 9
  • 10
  • See this answer for an explanation of the class hierarchy of JSON.NET: https://stackoverflow.com/a/38560188/8201661. When you have a variable of type `JToken`, but you know the value you have stored in that value is a `JObject` (or `JArray` or `JProperty`...), it's safe to cast that variable to `JObject` (or `JArray` or `JProperty`...) so you can access the more-specific fields and methods. – Nick Dec 27 '19 at 18:01
  • This solution certainly looks cleaner. It amazes me how simple it is but was struggling with it. Not sure how I would accept this without taking away credit from the previous answer - since it answers the question. – Kheel Dec 27 '19 at 20:03