skip to Main Content

Im trying to get a list of all the "Occupants" and "RiskId" from the JSON below using C# and Newtonsoft.

Not sure what I’m doing wrong here. Thanks for your help.

{
    "Header": {
        "MatchType": "Exact",
        "TotalResultCount": 2,
        "PreviousPageUrl": null,
        "NextPageUrl": null,
        "AvailableProductsForRequestedAddress": "https://prometrixapiuat.iso.com/uw/address/productList?City=MONTEBELLO&State=CA&StreetName=423+W+OLYMPIC+BLVD&Zip=90640"
    },
    "Risks": [
        {
            "RiskId": "64CX99016399",
            "BuildingDescription": "MONTEBELLO PLASTICS INC (1S)",
            "SurveyDates": {
                "ScheduleAppliedDate": "04/21/1999",
                "LatestPhoneSurveyDate": "",
                "OnsiteSurveyDate": "05/01/1999"
            },
            "Location": {
                "Latitude": null,
                "Longitude": null,
                "Address": {
                    "StreetAddress1": "423 W OLYMPIC BLVD",
                    "City": "MONTEBELLO",
                    "PostalCity": "MONTEBELLO",
                    "State": "CA",
                    "Zip": "90640",
                    "Zip4": "5225",
                    "County": "LOS ANGELES"
                },
                "AlternateAddresses": []
            },
            "Occupants": [
                {
                    "Name": "MFG STORAGE - PACKAGING MATERIALS",
                    "OccupantId": "15"
                }
            ],
            "ProductListUrl": "https://prometrixapiuat.iso.com/uw/Risk/64CX99016399/ProductList",
            "YearBuilt": 1960,
            "FireProtectionArea": "MONTEBELLO"
        },
        {
            "RiskId": "64CX99016400",
            "BuildingDescription": "MONTEBELLO PLASTICS INC (1S)",
            "SurveyDates": {
                "ScheduleAppliedDate": "04/21/1999",
                "LatestPhoneSurveyDate": "",
                "OnsiteSurveyDate": "05/01/1999"
            },
            "Location": {
                "Latitude": null,
                "Longitude": null,
                "Address": {
                    "StreetAddress1": "423 W OLYMPIC BLVD",
                    "City": "MONTEBELLO",
                    "PostalCity": "MONTEBELLO",
                    "State": "CA",
                    "Zip": "90640",
                    "Zip4": "5225",
                    "County": "LOS ANGELES"
                },
                "AlternateAddresses": []
            },
            "Occupants": [
                {
                    "Name": "MFG STORAGE - PACKAGING MATERIALS",
                    "OccupantId": "15"
                }
            ],
            "ProductListUrl": "https://prometrixapiuat.iso.com/uw/Risk/64CX99016400/ProductList",
            "YearBuilt": 1960,
            "FireProtectionArea": "MONTEBELLO"
        }
    ]
}

I would just like to loop through the list of "RiskId" and "Occupants" and display the value.

If I do ….

var jsonObj = (JObject)JsonConvert.DeserializeObject(jsonstring);

var jsonResult = jsonObj.SelectToken("Risks.RiskId").Select(m => m.Value<string>());

I’m getting below error

System.ArgumentNullException: ‘Value cannot be null.
Parameter name: source’

2

Answers


  1. You may do:

    var jsonResult = jsonObj.SelectTokens("Risks[*].RiskId")
        .Select(m => m.Value<string>())
        .ToList();
    

    Notes:

    1. The "RiskId" properties are nested in an array of objects Risks[*].RiskId, thus an array indexer such as [*] or [0] must be included in the path. [*] selects all RiskId properties.

    2. Since the "RiskId" properties are in an array and there is more than one, use SelectTokens() rather than SelectToken() to get them all.

    3. If you are unsure of the path to use to select a property by name, you may use the recursive descent operator .. to select all properties with that name, and then use JToken.Path to get the actual path of each.

      Thus, for your JSON,

      var paths = jsonObj.SelectTokens("...RiskId").Select(m => m.Path).ToList();
      

      Returns

      [
        "Risks[0].RiskId",
        "Risks[1].RiskId"
      ]
      

      From which you can see that the correct path to use in the original query should have been "Risks[*].RiskId".

    Demo here: https://dotnetfiddle.net/Lwrvdv

    Login or Signup to reply.
  2. I showed you this kind of code yesterday

    JArray risks = (JArray) JObject.Parse(jsonstring)["Risks"];
    
    var riskId = risks.Select(r => (string) r["RiskId"] ).FirstOrDefault(); // "64CX99016400"
        
    JArray occupants = risks.Select(r => (JArray) r["Occupants"] ).FirstOrDefault());
    

    UPDATE

    after @dbc update, if you can have several risks items, just remove firstordefault()

    string[] riskIds = risks.Select(r => (string) r["RiskId"] );
    
    Response.Write(string.Join(", ",riskIds)); // "64CX99016399, 64CX99016400"
    
    List<JArray> occupants = risks.Select(r => (JArray) r["Occupants"] ).ToList();
    
    int[] occupantIds = occupants.SelectMany(o => 
                                    o.Select(o => (int)o["OccupantId"])).ToArray();
    
    Response.Write(string.Join(", ",occupantIds)); // "15, 15";
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search