【问题标题】:Read json value using C# without using Property使用 C# 读取 json 值而不使用属性
【发布时间】:2020-03-29 06:47:22
【问题描述】:

我需要从以下 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" }      
    }
  ]
}

我尝试了以下代码但无法实现: 试一试:

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

尝试2:

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

【问题讨论】:

标签: c# json


【解决方案1】:

你可以使用

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();

【讨论】:

  • 谢谢 [AnuViswan],是否也可以使用测试用例名称获取 id,例如,我需要在 testCase.name 为“GetProjectTeamDetails”的情况下获取 Id,我试过这个:jObject.SelectToken($" $.value[?(@testCase.name=={"GetProjectTeamDetails"})].id"),但得到 json 异常
  • @SandeepDhamale 请检查答案中的更新。您需要 SelectTokens,因为根据 OP 中的示例可能有多个匹配结果
【解决方案2】:

您需要逐步了解层次结构。

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

【讨论】:

    【解决方案3】:

    另一种方法是使用dynamic关键字:

    dynamic jt = JToken.Parse(response);
    IEnumerable<dynamic> values = jt.value;
    string name = values.FirstOrDefault(v => v.id == 100000)?.testCase.name;
    

    【讨论】:

      【解决方案4】:

      其他答案已使用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);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-23
        • 2015-08-14
        • 1970-01-01
        • 1970-01-01
        • 2012-06-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多