PixelPaul PixelPaul - 4 months ago 32
C# Question

Get value from IEnumerable foreach loop

I need to create a c# object from a JSON file, and have to following working solution:

JSON:

{
"AK": {
"Anchorage": [{
"Name": "John Doe",
"Address": "123 Main St.",
"City": "Anchorage",
"State": "AK",
"Zip": "12345"
}],
"Fairbanks": [{
"Name": "Sally Smith",
"Address": "987 Main St.",
"City": "Fairbanks",
"State": "AK",
"Zip": "98765"
}]
}
}


Code:

public class Location
{
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}

// ------------------------------------------------------------------
string json = File.ReadAllText(@"C:json.txt");
dynamic deserialisedJson = JsonConvert.DeserializeObject(json);

var locations = new List<Location>();

foreach (var root in deserialisedJson)
{
foreach (var state in root)
{
foreach (var city in state)
{
foreach (var location in city)
{
Location loc = new Location();
loc.Name = location.First["Name"];
loc.Address = location.First["Address"];
loc.City = location.First["City"];
loc.State = location.First["State"];
loc.Zip = location.First["Zip"];
locations.Add(loc);
}
}
}
}


But I need to incorporate the above into an SSIS package, which only allows .NET 3.5 and below. The line of code below requires .NET 4.0 and above:

dynamic deserialisedJson = JsonConvert.DeserializeObject(json);


I'm trying to workaround this limitation by using IEnumerable, but I'm not sure of the syntax of how to grab the values I need?

string json = File.ReadAllText(@"C:json.txt");

var deserialisedJson = (IEnumerable)JsonConvert.DeserializeObject(json);

var locations = new List<Location>();

foreach (var root in deserialisedJson)
{
foreach (var state in (IEnumerable)root)
{
foreach (var city in (IEnumerable)state)
{
foreach (var location in (IEnumerable)city)
{
Location loc = new Location();

loc.Name = //What goes here???
loc.Address = //What goes here???
loc.City = //What goes here???
loc.State = //What goes here???
loc.Zip = //What goes here???

locations.Add(loc);
}
}
}
}

Answer

This uses Linq to JSON to select all the Location objects you want:

var deserialisedJson = (IEnumerable)JsonConvert.DeserializeObject(json);
JObject jObj = JObject.Parse(json);

//Get all tokens that are under AK/(some descendant)/all items from collection
var result = jObj.SelectTokens("AK.*.[*]")
                    .Select(x => new Location
                    {
                        Name = x["Name"].Value<string>(),
                        Address = x["Address"].Value<string>(),
                        City = x["City"].Value<string>(),
                        State = x["State"].Value<string>(),
                        Zip = x["Zip"].Value<string>(),
                    }).ToList();

Tested and this works in a .Net 3.5 project with a Newtonsoft.Json package suitable for the .Net