0

Sorry for the nube-like question, but having been retired for sometime I find myself forgetting some things.

Given this sample json string:

{
    "range": [
        { "num": 0 },
        { "num": 1 },
        { "num": 2 },
        { "num": 3 },
        { "num": 4 },
        { "num": 5 },
        { "num": 6 },
        { "num": 7 },
        { "num": 8 },
        { "num": 9 }
    ],
    "friends": [
      {
        "id": 0,
        "name": "Christian Cruz"
      },
      {
        "id": 1,
        "name": "Hunter Moon"
      },
      {
        "id": 2,
        "name": "Holden Gentry"
      }
    ]
}

I would like to be able to read the root value ("range" and "friends" in this case) for each line in the data, then parse the remaining values.

void Main()
{
    var json = File.ReadAllText(@"c:\data\sample.json");
    JObject obj = JObject.Parse(json);
    foreach(JProperty child in obj.Children())
    {

    }
} 

Where I bogged down is as I iterate through the children collection (foreach(JProperty child ...) I can read the items in the array (e.g. "num", "id" and "name") but I am unable to read the root values (e.g. "range" and "friends")

Any help you could lend an old man would be very much appreciated.

2
  • 1
    If you deserialize it, the resulting class will have both collections in one or two lines of code Commented Jul 21, 2018 at 16:18
  • 2
    Works for me; looking at the Name property of each child shows the property's name as expected: dotnetfiddle.net/GvRsYe Commented Jul 21, 2018 at 16:33

3 Answers 3

3

It's much easier to deserialise it into C# objects, for example:

public class RootObject
{
    public List<Range> range { get; set; }
    public List<Friend> friends { get; set; }
}

public class Range
{
    public int num { get; set; }
}

public class Friend
{
    public int id { get; set; }
    public string name { get; set; }
}

Now you can use deserialise like this:

var root = JsonConvert.DeserializeObject<RootObject>(json);

And use the data:

foreach (var range in root.Range)
{
    //Do stuff
}

foreach (var friend in root.Friends)
{
    //Do stuff
}
Sign up to request clarification or add additional context in comments.

6 Comments

Or just use a dynamic object if you want to skip making a bunch of classes: Deserialize JSON into C# dynamic object?
@HereticMonkey Ugh, no. If one of my developers brought that to me, I''d tell them to go and make the classes. It's trivial to do, and there's even websites that do it for you.
Sure, but since the OP mentions he's retired, I figured it's a safe bet it's not for professional work... :)
Professional or not, I'm sure OP would prefer to do things the "right" way
The "right" way would be to rename those classes/properties to follow conventions :) (I've seen too many times people leaving that RootObject in production code...)
|
2

You can use SelectTokens , put the json in list and then iterate through JProperty.

var files = JObject.Parse(YourJson);
var recList = files.SelectTokens("$").ToList();
        foreach (JProperty item in recList.Children())
        {
            var key = item.Name.ToString(); //store the root item here
            var value = item.Value.ToString();
            //Do your stuffs
        }

Comments

0

Using this small recursive function below you can unpack JSON to see properties as well as values without making any classes

static void Main(string[] args)
{
    var json = "{\"range\":[{\"num\":0},{\"num\":1},{\"num\":2},{\"num\":3},{\"num\":4},{\"num\":5},{\"num\":6},{\"num\":7},{\"num\":8},{\"num\":9}],\"friends\":[{\"id\":0,\"name\":\"Christian Cruz\"},{\"id\":1,\"name\":\"Hunter Moon\"},{\"id\":2,\"name\":\"Holden Gentry\"}]}";

    JObject obj = JObject.Parse(json);

    void UnpackJson(JToken jobj, int indent)
    {
        if (jobj == null)
            return;

        var name = (jobj as JProperty)?.Name;
        if (name != null)
        {
            Console.Write(new string(' ', indent) + name + " :\n");
            indent += 4;
        }

        foreach (var child in jobj.Children())
        {
            var chname = (child as JProperty)?.Name;
            if (chname != null)
                Console.Write(new string(' ', indent) + chname + " : ");

            var value = (child as JProperty)?.Value;
            if (child.Values().Count() > 1)
            {
                if (chname != null || name != null)
                    Console.WriteLine();

                IEnumerable<JToken> jt = (value is JArray) ? child.Values() : child.Children();

                foreach (var val in jt)
                    UnpackJson(val, indent + 4);
            }
            else
            {
                if (value != null)
                    Console.WriteLine(value);
            }
        }
    }

    UnpackJson(obj, 0);

    Console.Read();
}

Output:

range :
    num : 0
    num : 1
    num : 2
    num : 3
    num : 4
    num : 5
    num : 6
    num : 7
    num : 8
    num : 9
friends :
    id : 0
    name : Christian Cruz
    id : 1
    name : Hunter Moon
    id : 2
    name : Holden Gentry

Comments

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.