3

I need to read the value of testCase.name for id 100000 from following JSON response string.

response = {
  "count": 2,
  "value": [
    {
      "id": 100000,
      "project": {
        "id": "aaaa-bbbb-cccc-dddd",
        "name": "MyTestProject",
        "url": "https://dev.azure.com/MyOrg/_apis/projects/MyTestProject"
      },      
      "testCase": { "name": "GetProjectTeamDetails" }
     }, 
    {
      "id": 100001,
      "project": {
        "id": "aaaa-bbbb-cccc-dddd",
        "name": "MyTestProject",
        "url": "https://dev.azure.com/MyOrg/_apis/projects/MyTestProject"
      },      
      "testCase": { "name": "QueueBuild" }      
    }
  ]
}

I've tried the following codes but could not achieve: Try1:

JObject o = JObject.Parse(response)
string testCaseName= (string)o["values"][0];

Try2:

 JObject jObject = JObject.Parse(response);
 string displayName = (string)jObject.SelectToken("testCase.name");
Fred
  • 3,365
  • 4
  • 36
  • 57
Sandeep Dhamale
  • 459
  • 2
  • 7
  • 22
  • Does this answer your question? [Searching for a specific JToken by name in a JObject hierarchy](https://stackoverflow.com/questions/19645501/searching-for-a-specific-jtoken-by-name-in-a-jobject-hierarchy) and [Querying JSON with JSONPath or SelectTokens?](https://stackoverflow.com/questions/30804299/querying-json-with-jsonpath-or-selecttokens-with-json-net-in-c-sharp) – Pavel Anikhouski Mar 29 '20 at 09:16

4 Answers4

4

You could use

var jo = JObject.Parse(json);
var testCaseName  = (string)jo.SelectToken($"$.value[?(@id=={idToSearch})].testCase.name");

Update

Base on your question in comment, you could find the ID with test case name using

jo.SelectTokens($"$.value[?(@testCase.name=='{nameToSearch}')].id")

Please note in this case, you would need to use .SelectTokens as there is chances of duplicates as give in the example in OP. You could get all the results or the first based on your requirement.

var idList  = jo.SelectTokens($"$.value[?(@testCase.name=='{nameToSearch}')].id")
                 .Select(x=> long.Parse(x.ToString()));
var onlyFirst = (long)jo.SelectTokens($"$.value[?(@testCase.name=='{nameToSearch}')].id")
                 .First();
Anu Viswan
  • 17,797
  • 2
  • 22
  • 51
  • 1
    THanks [AnuViswan], Is it also possible to get id using the test case name e.g I need to fetch Id where testCase.name is "GetProjectTeamDetails", I tried this: jObject.SelectToken($"$.value[?(@testCase.name=={"GetProjectTeamDetails"})].id"), but getting json exception – Sandeep Dhamale Mar 29 '20 at 07:43
  • 1
    @SandeepDhamale Please check the update in answer. You would need to SelectTokens as there could be multiple matching results as per the example in OP – Anu Viswan Mar 29 '20 at 07:49
1

You need to step through hierarchy.

JObject jObject = JObject.Parse(jsonString);
var testCaseName = jObject.SelectToken("value[0].testCase.name").ToString();
1

Another approach is using dynamic keyword:

dynamic jt = JToken.Parse(response);
IEnumerable<dynamic> values = jt.value;
string name = values.FirstOrDefault(v => v.id == 100000)?.testCase.name;
Mohsen Esmailpour
  • 11,224
  • 3
  • 45
  • 66
1

The other answers have shown using SelectToken, which is fine - if you don't want to do that, you can still do it by accessing one property at a time:

using System;
using System.IO;
using Newtonsoft.Json.Linq;

class Test
{
    static void Main()
    {
        string json = File.ReadAllText("test.json");
        JObject obj = JObject.Parse(json);
        string testCase = (string) obj["value"][0]["testCase"]["name"];
        Console.WriteLine(testCase);
    }
}

In your Try1 you're using values instead of value, and you're stopping at the array - you're not asking for the testCase property, or the name property within that.

In your Try2 you're doing exactly the opposite - you're looking for testCase.name without selecting an element within the value array first.

As one third way, you could use dynamic typing:

using System;
using System.IO;
using Newtonsoft.Json.Linq;

class Test
{
    static void Main()
    {
        string json = File.ReadAllText("test.json");
        dynamic obj = JObject.Parse(json);
        string testCase = obj.value[0].testCase.name;
        Console.WriteLine(testCase);
    }
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194