Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get list of values by key's name across Json using C#

Tags:

json

c#

json.net

I have a Json file as below

{
  "objectId": "123",
  "properties": {
    "objectId": "456"
  },
  "variables": [
    {
      "objectId": "789"
    },
    {
      "objectId": "012"
    }
  ]

}

I want to get all 'objectId's in a list like [ "123", "456", "789", "012" ]

I tried as below

var body = JObject.Parse(jsonString); //using Newtonsoft library
var list = body.Properties().Where(p => p.Name == "objectId").Select(p => p.Value).ToList();

I tried in a below way too

var list = new List<string>();
            foreach(var prop in body.Properties())
            {
                if(prop.Name == "objectId")
                {
                    list.Add(prop.Value.ToString());
                }
            }

But here i get only first level properties.

like image 242
KBNanda Avatar asked Sep 04 '19 05:09

KBNanda


2 Answers

Use the DescendantsAndSelf().OfType() to get all JProperties, and then filter with LINQ.

var root = (JContainer)JToken.Parse(json);
            var list = root.DescendantsAndSelf().OfType<JProperty>().Where(p => p.Name == "objectId").Select(p => p.Value.Value<string>());
            Console.WriteLine(string.Join(",", list.ToArray()));
like image 176
Peter-Yu Avatar answered Oct 24 '22 16:10

Peter-Yu


 IEnumerable<JToken> AllTokens(JObject obj)
        {
            var toSearch = new Stack<JToken>(obj.Children());
            while (toSearch.Count > 0)
            {
                var inspected = toSearch.Pop();
                yield return inspected;
                foreach (var child in inspected)
                {
                    toSearch.Push(child);
                }
            }
        }

Then you can use linq to filter and perform action:

    var tokens = AllTokens(body);
    var data = tokens.Where(t => t.Type == JTokenType.Property && ((JProperty)t).Name == "objectId")
    .Select(x=> ((JProperty)x).Value.Value<string>()).ToList();
like image 40
AmirNorouzpour Avatar answered Oct 24 '22 18:10

AmirNorouzpour