使用C#读取JSON值而不使用属性

3
我需要从以下JSON响应字符串中读取ID为100000的testCase.name的值。
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" }      
    }
  ]
}

我尝试了以下代码,但没有成功: 尝试1:

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

尝试2:

 JObject jObject = JObject.Parse(response);
 string displayName = (string)jObject.SelectToken("testCase.name");

4个回答

4

您可以使用

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

更新

根据您在评论中的问题,您可以使用以下方式通过测试用例名称找到ID:

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

请注意,在这种情况下,您需要使用.SelectTokens,因为OP示例中存在重复项的可能性。根据您的需求,您可以获取所有结果或第一个结果。
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();

1
谢谢[AnuViswan],是否也可以通过测试用例名称获取id,例如我需要获取testCase.name为“GetProjectTeamDetails”的Id,我尝试了这个:jObject.SelectToken($"$.value[?(@testCase.name=={"GetProjectTeamDetails"})].id"),但是出现了json异常。 - Sandeep Dhamale
1
@SandeepDhamale 请检查答案中的更新。您需要选择令牌,因为根据OP中的示例可能会有多个匹配结果。 - Anu Viswan

1

你需要逐级进行层次结构。

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

1
另一种方法是使用 dynamic 关键字:
dynamic jt = JToken.Parse(response);
IEnumerable<dynamic> values = jt.value;
string name = values.FirstOrDefault(v => v.id == 100000)?.testCase.name;

1
其他答案已经展示了如何使用SelectToken,这是可以的 - 如果你不想这样做,你仍然可以通过逐个访问一个属性来实现:
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);
    }
}

在您的Try1中,您使用了values而不是value,并且在数组处停止 - 您没有请求testCase属性或其中的name属性。
在您的Try2中,您正好相反 - 您正在寻找testCase.name,而没有首先选择value数组中的元素。
作为第三种方法,您可以使用动态类型:
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);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接