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.

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

Comments

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);
}

2 Comments

See this answer for an explanation of the class hierarchy of JSON.NET: 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.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.