Search code examples
c#arraysjsonjson-deserialization

Parse JSON string using JSON.NET and create a list of strings from a specific array member


What I'm trying to do is make a List<string> of all the "description"'s for each address prediction, as the other data isn't relevant to this project. This is the JSON I'm working with:

{
   "predictions" : [
      {
         "description" : "123 Fake Street, Chuxiong, Yunnan, China",
         "id" : "7e358b51222e27748f2edb85fdced03ce521a8d1",
         "matched_substrings" : [
            {
               "length" : 15,
               "offset" : 0
            }
         ],
         "place_id" : "EigxMjMgRmFrZSBTdHJlZXQsIENodXhpb25nLCBZdW5uYW4sIENoaW5h",
         "reference" : "CmRWAAAAkvZoFSAdrZVT-kn39UmjrxpNLA8EHBVHD4wWk1gh-fJ9eRfYKXI3MPC-WgkSBvqjYH1y9zGJJhzkirL1gh_tdzWOCg5PxpeWJInJhrL6iJpDRYM9SE-vRrnzvwRcKmFkEhCC1kdbeGjmZzhICnOQgBeyGhRr4JloDu9qsNvfNgWnT7TjomYnMQ",
         "structured_formatting" : {
            "main_text" : "123 Fake Street",
            "main_text_matched_substrings" : [
               {
                  "length" : 15,
                  "offset" : 0
               }
            ],
            "secondary_text" : "Chuxiong, Yunnan, China"
         },
         "terms" : [
            {
               "offset" : 0,
               "value" : "123 Fake Street"
            },
            {
               "offset" : 17,
               "value" : "Chuxiong"
            },
            {
               "offset" : 27,
               "value" : "Yunnan"
            },
            {
               "offset" : 35,
               "value" : "China"
            }
         ],
         "types" : [ "route", "geocode" ]
      },
      {
         "description" : "123 Fake Road, York, PA, United States",
         "id" : "0bc5d3a9d8627eeed8da28434a65a5732470ae62",
         "matched_substrings" : [
            {
               "length" : 13,
               "offset" : 0
            }
         ],
         "place_id" : "EiYxMjMgRmFrZSBSb2FkLCBZb3JrLCBQQSwgVW5pdGVkIFN0YXRlcw",
         "reference" : "CmRUAAAAJ2xHFZSOF_UUjGB9RI5TMFUsHWUeo2TBEjUu8lGJ9IDX-hegwwkOvsPADTet0Xqsw0IJ6tlIRByCR52rKJuGrwQ2-dBFiFqfYViJFxsUpTqcuwhyXuieBWhixBI3HdXUEhCXLWrK158AahJT9L0AARhAGhSJ6kXvCjpcQ_UOxLe_lUGddkgj9g",
         "structured_formatting" : {
            "main_text" : "123 Fake Road",
            "main_text_matched_substrings" : [
               {
                  "length" : 13,
                  "offset" : 0
               }
            ],
            "secondary_text" : "York, PA, United States"
         },
         "terms" : [
            {
               "offset" : 0,
               "value" : "123 Fake Road"
            },
            {
               "offset" : 15,
               "value" : "York"
            },
            {
               "offset" : 21,
               "value" : "PA"
            },
            {
               "offset" : 25,
               "value" : "United States"
            }
         ],
         "types" : [ "route", "geocode" ]
      },
      {
         "description" : "123 Fake Drive, Luray, VA, United States",
         "id" : "8f24aaae29e3c66d166b474078a764f67752b6b0",
         "matched_substrings" : [
            {
               "length" : 14,
               "offset" : 0
            }
         ],
         "place_id" : "EigxMjMgRmFrZSBEcml2ZSwgTHVyYXksIFZBLCBVbml0ZWQgU3RhdGVz",
         "reference" : "CmRWAAAAo4DSwUPKoaYCbnXEVLN-XPYjwrdLeu9r5NbhMStAYXbDhRkxfl1kS_8sYA-ppwyiAj2-MpBwTy2-P3Vo8yCEAmy5JqZwBtdImKRHGwCw8fY7UFXYJO7yhaUyFE-41z25EhBU6Ne6JR94DU7zl168LyUhGhS9xQHoi_zd9AMsDfp84w8Ol5hCXQ",
         "structured_formatting" : {
            "main_text" : "123 Fake Drive",
            "main_text_matched_substrings" : [
               {
                  "length" : 14,
                  "offset" : 0
               }
            ],
            "secondary_text" : "Luray, VA, United States"
         },
         "terms" : [
            {
               "offset" : 0,
               "value" : "123 Fake Drive"
            },
            {
               "offset" : 16,
               "value" : "Luray"
            },
            {
               "offset" : 23,
               "value" : "VA"
            },
            {
               "offset" : 27,
               "value" : "United States"
            }
         ],
         "types" : [ "route", "geocode" ]
      },
      {
         "description" : "123 Fake Lane, Orangeburg, SC, United States",
         "id" : "d3d3f49c60871bac676f5872ed7d04bff3a2d737",
         "matched_substrings" : [
            {
               "length" : 13,
               "offset" : 0
            }
         ],
         "place_id" : "EiwxMjMgRmFrZSBMYW5lLCBPcmFuZ2VidXJnLCBTQywgVW5pdGVkIFN0YXRlcw",
         "reference" : "CmRaAAAAWkmzLjcStucl1QuYHjQdip4h7zK9H6WmcnFlVR09FQf4iQSDAb04G1KHC55-ah_za5PaGNtvAf-Qh7EOrVwBcbCvhlIeje_RFJgqPM2mAqi8Joc_pufBOlOjQ8WAlAmGEhBM5xgeFZ0igc1JDxFjbmZ9GhROPsh63HGcp_baMGel8ln3WIUrjg",
         "structured_formatting" : {
            "main_text" : "123 Fake Lane",
            "main_text_matched_substrings" : [
               {
                  "length" : 13,
                  "offset" : 0
               }
            ],
            "secondary_text" : "Orangeburg, SC, United States"
         },
         "terms" : [
            {
               "offset" : 0,
               "value" : "123 Fake Lane"
            },
            {
               "offset" : 15,
               "value" : "Orangeburg"
            },
            {
               "offset" : 27,
               "value" : "SC"
            },
            {
               "offset" : 31,
               "value" : "United States"
            }
         ],
         "types" : [ "route", "geocode" ]
      },
      {
         "description" : "123 Fake Hollow Road, York, PA, United States",
         "id" : "4211cef659a1322f42e85183cb41e75d2b6ae65a",
         "matched_substrings" : [
            {
               "length" : 20,
               "offset" : 0
            }
         ],
         "place_id" : "Ei0xMjMgRmFrZSBIb2xsb3cgUm9hZCwgWW9yaywgUEEsIFVuaXRlZCBTdGF0ZXM",
         "reference" : "CmRbAAAAOVlDirZh2WjzSXj28VM2peJHG9rTiQ57hqtTr94dCLAQezuZJJT4dqFC8B9TFyddBfhDDMrbSwZro9RkLkvLzxb95XHtzfb1ZnlCNVfK9_K4rEHHwcQ7Ndd3l8x5GNXGEhBDc6mw6iyjYcOVZo44mLwvGhSNaBwDy9OgIAyNa8_gvSyQ3bC3cQ",
         "structured_formatting" : {
            "main_text" : "123 Fake Hollow Road",
            "main_text_matched_substrings" : [
               {
                  "length" : 20,
                  "offset" : 0
               }
            ],
            "secondary_text" : "York, PA, United States"
         },
         "terms" : [
            {
               "offset" : 0,
               "value" : "123 Fake Hollow Road"
            },
            {
               "offset" : 22,
               "value" : "York"
            },
            {
               "offset" : 28,
               "value" : "PA"
            },
            {
               "offset" : 32,
               "value" : "United States"
            }
         ],
         "types" : [ "route", "geocode" ]
      }
   ],
   "status" : "OK"
}

This is the most relevant documentation I can find, but when I try the same approach using this code,

DataSet pleaseWork = JsonConvert.DeserializeObject<DataSet>(thisIsMyJsonString);
DataTable pleaseWorkAgain = pleaseWork.Tables["predictions"];

this is the error I get:

Newtonsoft.Json.JsonSerializationException: 'Unexpected JSON token when reading DataTable: StartObject. Path 'predictions[0].structured_formatting'

I think that occurs because the example's JSON isn't nested as deeply as what I'm working with, but I'm not entirely sure.


Solution

  • The below should work for you.

    List<String> addressList = new List<string>();
    dynamic pleaseWork = JsonConvert.DeserializeObject(thisIsMyJsonString);
    foreach (var obj in pleaseWork.predictions)
    {
        addressList.Add(obj.description.Value);
    }