C# 使用 Newtonsoft.json 从 JSON 字符串中检索特定信息

C# Retrieving a specific piece of information from JSON string by using Newtonsoft.json

JSON 我检索到的字符串:

{
  "trackItemResponse" : {
    "hdr" : {
      "messageType" : "TRACKITEM",
      "messageDateTime" : "2021-04-28T16:32:05+08:00",
      "messageVersion" : "1.0",
      "messageLanguage" : "en"
    },
    "bd" : {
      "shipmentItems" : [ {
        "masterShipmentID" : null,
        "shipmentID" : "MYCGUMY8202104SIN00005",
        "trackingID" : "5021049762931421",
        "orderNumber" : null,
        "handoverID" : null,
        "shippingService" : {
          "productCode" : "PDO",
          "productName" : "Parcel Domestic"
        },
        "consigneeAddress" : {
          "country" : "MY"
        },
        "weight" : "804",
        "dimensionalWeight" : "640",
        "weightUnit" : "G",
        "events" : [ {
          "status" : "77093",
          "description" : "Successfully delivered",
          "dateTime" : "2021-04-06 13:47:56",
          "timezone" : "LT",
          "address" : {
            "city" : "Skudai",
            "postCode" : "81300",
            "state" : "JOHOR",
            "country" : "MY"
          }
        }, {
          "status" : "77090",
          "description" : "Out for Delivery",
          "dateTime" : "2021-04-06 10:51:55",
          "timezone" : "LT",
          "address" : {
            "city" : "Skudai",
            "postCode" : "81300",
            "state" : "JOHOR",
            "country" : "MY"
          }
        }, {
          "status" : "77184",
          "description" : "Processed at delivery facility",
          "dateTime" : "2021-04-06 07:56:07",
          "timezone" : "LT",
          "address" : {
            "city" : "Skudai",
            "postCode" : "81300",
            "state" : "Johor",
            "country" : "MY"
          }
        }, {
          "status" : "77178",
          "description" : "Arrived at facility",
          "dateTime" : "2021-04-06 07:30:26",
          "timezone" : "LT",
          "address" : {
            "city" : "Skudai",
            "postCode" : "81300",
            "state" : "Johor",
            "country" : "MY"
          }
        }, {
          "status" : "77169",
          "description" : "Departed from facility",
          "dateTime" : "2021-04-06 05:22:02",
          "timezone" : "LT",
          "address" : {
            "city" : "Kuala Lumpur Hub",
            "postCode" : "47100",
            "state" : "Kuala Lumpur",
            "country" : "MY"
          }
        }, {
          "status" : "77027",
          "description" : "Sorted to delivery facility",
          "dateTime" : "2021-04-05 21:00:05",
          "timezone" : "LT",
          "address" : {
            "city" : "Kuala Lumpur Hub",
            "postCode" : "47100",
            "state" : "Kuala Lumpur",
            "country" : "MY"
          }
        }, {
          "status" : "77015",
          "description" : "Processed at facility",
          "dateTime" : "2021-04-05 20:59:04",
          "timezone" : "LT",
          "address" : {
            "city" : "Kuala Lumpur Hub",
            "postCode" : "47100",
            "state" : "Kuala Lumpur",
            "country" : "MY"
          }
        }, {
          "status" : "71005",
          "description" : "DATA SUBMITTED",
          "dateTime" : "2021-04-02 15:44:40",
          "timezone" : "Malaysia",
          "address" : {
            "city" : "SEPANG, SELANGOR",
            "postCode" : "43900",
            "state" : "SEL",
            "country" : "MY"
          }
        } ]
      } ],
      "responseStatus" : {
        "code" : "200",
        "message" : "SUCCESS",
        "messageDetails" : [ {
          "messageDetail" : "1 tracking reference(s) tracked, 1 tracking reference(s) found."
        } ]
      }
    }
  }
}

我想要的输出:

5021049762931421 //trackingID

Method_1 我试过:

HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
     string result = streamReader.ReadToEnd();
     Console.WriteLine(result);
     dynamic data = JObject.Parse(result);
     Console.WriteLine(data.trackItemResponse.bd.shipmentItems.trackingID);
}

输出:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ''Newtonsoft.Json.Linq.JArray' does not contain a definition for 'trackingID''

Method_2 我试过:

HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
     var trckID = JObject.Parse(result)["trackItemResponse"]["bd"]["shipmentItems"].Select(x => (string)x["trackingID"]).ToList();
     Console.WriteLine("Below is json data");
     Console.WriteLine(trckID);
     Console.WriteLine("Until here la");
}

Output_2:

Below is json data
System.Collections.Generic.List`1[System.String]
Until here la

Method_3 我试过:

HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
     string jsonData = JObject.Parse(result)["trackItemResponse"]["bd"]["shipmentItems"]["trackingID"].ToString();
     Console.WriteLine("Below is json data");
     Console.WriteLine(jsonData);
     Console.WriteLine("Until here la");
}

Output_3:

System.ArgumentException: 'Accessed JArray values with invalid key value: "trackingID". Int32 array index expected.'

还有其他可行的方法吗?谢谢。

Post 我已经提到了

Convert string to int C#

C# cast from string to int/int32

感谢您的帮助!

您正在寻找

var result = JObject.Parse(result)["trackItemResponse"]["bd"]["shipmentItems"][0]["trackingID"].ToString();

但请记住,shipmentItems 是一个列表,因此可以包含多个项目。
此代码仅检查该列表中的第一个。

SelectToken就是您要找的:

var semiParsedJson = JObject.Parse(json);
var trackingId = semiParsedJson
    .SelectToken("trackItemResponse.bd.shipmentItems[0].trackingID");

请记住,此解决方案假定 shipmentItems 集合中的第一个对象包含所需信息。

如果不存在,则 trackingId 将是 null


如果 shipmentItems 中有多个对象并且您对所有 trackingId 值感兴趣,那么您必须使用 SelectTokens

var semiParsedJson = JObject.Parse(json);
var trackingIds = semiParsedJson
    .SelectTokens("trackItemResponse.bd.shipmentItems[*].trackingID");

请注意,索引器运算符现在收到一个 * 通配符。

从您的代码来看,您几乎已经完成了。 由于对象“data.trackItemResponse.bd.shipmentItems”是数组,选择索引后需要访问“trackingID”

您的代码应该是:

HttpWebResponse httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
     string result = streamReader.ReadToEnd();
     Console.WriteLine(result);
     dynamic data = JObject.Parse(result);
     
     //Test this 
     var trackingID = data.trackItemResponse.bd.shipmentItems[0].trackingID;
     Console.WriteLine(data.trackItemResponse.bd.shipmentItems[0].trackingID);
}