-2

I'm using C# with Json.NET NuGet. I have JSON that looks like this:

{
    "pre" : "",
    "options": {
        "0001" : {
            "id" : "0001",
            "desc" : "first"
        },
        "0002" : {
            "id" : "0002",
            "desc" : "second"
        },
        "0003" : {
            "id" : "0003",
            "desc" : "third"
        }
    },
    "post" : ""
}
  1. How can I query the above Json to get a List<JObject> with the 3 option items in it?
  2. Or/Also How can I get just the second item where item 2 should be:

    {
        "id" : "0002",
        "desc" : "second"
    }
    

I've tried stuff like

var items = json.SelectTokens("options[*]").ToList();

and

var item = json.SelectTokens("options[1]");

but those clearly don't work.

EDIT:

In case I wasn't clear I DO NOT want to deserialize. I want a List<JObject>.

LorneCash
  • 1,446
  • 2
  • 16
  • 30
  • Does this answer your question? [How can I deserialize a child object with dynamic (numeric) key names?](https://stackoverflow.com/questions/24771804/how-can-i-deserialize-a-child-object-with-dynamic-numeric-key-names) – Sir Rufo Jan 26 '20 at 00:28
  • No because I'm NOT trying to deserialize. – LorneCash Jan 26 '20 at 00:32
  • "Converting" to JObject ..... IS deserializing! So you might as well just create the correct model and use JsonConvert.DeserializeObject... Save your self some pain. – Jonathan Alfaro Jan 26 '20 at 01:28
  • I'm not in control of the JSON and it changes structure semi frequently so I'm actually saving myself massive time by leaving it as JSON and not deserializing. – LorneCash Jan 26 '20 at 08:05

3 Answers3

1

Your json is valid but your thinking of this json is not quite accurate.

You are thinking that options have a list of objects that you want to iterate over, but, thats not the case. options is not a list but an object that has more objects within it.. Not an array.

You can access each of the element within the JObject by first looking up its properties. Properties are 0001, 0002 etc. Once you have those, you can iterate over the properties of options and get the values you need.

    JObject options = (JObject)JObject.Parse(json)["options"];

    // Get a list of all tokens within this object.
    List<JObject> allObjects = new List<JObject>();
    foreach (var node in options.Properties())
        allObjects.Add((JObject)options[node.Name]);

    // Access the IDs
    allObjects.ForEach(x => Console.WriteLine(x["id"].ToString()));

    // Access the 2nd ID only
    Console.WriteLine(); // Just to space it out.
    Console.WriteLine(allObjects[1]["id"].ToString());

Output

0001
0002
0003

0002
Jawad
  • 11,028
  • 3
  • 24
  • 37
  • My understanding was correct, I thought that was clear in the old title "How get List of JSON Objects NOT from within a JSON array" but I've updated it to hopefully be more clear. – LorneCash Jan 26 '20 at 07:50
1

You could create the required List using Linq. For example,

var list = ((JObject)JObject.Parse(str)["options"])
                            .Properties()
                            .Select(x=>x.Value)
                            .Cast<JObject>()
                            .ToList();

For accessing the second element, you could use

var secondId = (string)list[1]["id"];
var secondDesc = (string)list[1]["desc"];
Anu Viswan
  • 17,797
  • 2
  • 22
  • 51
  • I'm not starting with a string, I'm starting with a JObject. I know I could convert the JObject to a string and then back to a JObject but I'm looking for a way to do it with a query. – LorneCash Jan 28 '20 at 16:56
  • I did find the solution I was looking for but thank you for yours. – LorneCash Jan 28 '20 at 16:57
0

I was actually close but trying too hard:

var items = json.SelectToken("options").ToList();

I was unable to figure out how to get a single option from a query but since I got the whole list I did it like this:

var item = json.SelectToken("options").ToList()[1];

LorneCash
  • 1,446
  • 2
  • 16
  • 30