1

JSON string that i retrieved:

{
  "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."
        } ]
      }
    }
  }
}

Output that i wanted:

5021049762931421 //trackingID

Method_1 that i've tried:

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

Output:

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

Method_2 that i've tried:

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 that i've tried:

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.'

Is there any other methods that could work? Thank you.

Post that i've refered

Convert string to int C#

C# cast from string to int/int32

Make newtonsoft.json convert default to int32 rather than int64

C# extract json array with newtonsoft.json

Thank you for your kind assistance!

Kelvin Yong
  • 70
  • 1
  • 8

3 Answers3

1

You are looking for

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

But keep in mind that shipmentItems is a list, so could contain multiple items.
This code only checks the first in that list.

Connor Stoop
  • 1,574
  • 1
  • 12
  • 26
1

SelectToken is what you are looking for:

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

Please bear in mind that this solution assumes that the first object in the shipmentItems collection contains the required information.

If it is not present then trackingId will be null.


If you have multiple objects inside the shipmentItems and you are interested about all of the trackingId values then you have to use SelectTokens

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

Please note that the indexer operator now receives a * wildcard.

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
1

From your code, you are almost there. Since the object "data.trackItemResponse.bd.shipmentItems" is an array, you need to access the "trackingID" after selecting the index.

Your code should be:

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