0

I have a block of code that works in .NET 4.0+, but I need to use this code in an SSIS package that only supports up to .NET 3.5. The problem is I can't use the dynamic object below 4.0. I'm unable to find a workaround, any ideas?

            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.CafeId = location.First["cafeID"];
                            loc.CafeName = location.First["cafeName"];
                            loc.CafeState = location.First["cafeState"];
                            loc.CafeCity = location.First["cafeCity"];
                            loc.CafeStreetName = location.First["cafeStreetName"];
                            loc.CafeZip = location.First["cafeZip"];

                            locations.Add(loc);
                        }
                    }
                }
            }

UPDATE Adding JSON schema

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

}

UPDATE 2

I am attempting the IEnumerable workaround, but not sure what the correct syntax is so that I can 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);
                        }
                    }
                }
            }
PixelPaul
  • 2,609
  • 4
  • 39
  • 70
  • How about `IEnumerator deserialisedJson = (IEnumerator)JsonConvert.DeserializeObject(json);`? (and for the inner objects too). – René Vogt Aug 02 '16 at 11:51
  • have you tried to implement the root, state and city objects? since we can't see the JSON I can't bring up a code sample, but that should do it really. Try to read through the JSON and figure out what makes up each object – MichaelThePotato Aug 02 '16 at 11:52
  • What would an `IEnumerator` solution look like? – PixelPaul Aug 02 '16 at 15:53

2 Answers2

0

from another post - Newtonsoft JSON Deserialize

class MyData
{
    public string t;
    public bool a;
    public object[] data;
    public string[][] type;
}

and then use the generic version of DeserializeObject:

MyData tmp = JsonConvert.DeserializeObject<MyData>(json);
foreach (string typeStr in tmp.type[0])
{
    // Do something with typeStr
}
Community
  • 1
  • 1
Arun Prasad E S
  • 9,489
  • 8
  • 74
  • 87
0

Without an example json I can only speculate - but it looks like you know the (relevant) schema of your json already. You don't need dynamic in the first place, and even in .net 4.0 and higher I'd advise against using it. Code using dynamic is typically slower, more error prone, and harder to debug than code which is statically typed not just because of compile-time checks, but also because errors at runtime appear earlier.

From your limited example and without knowing what that First thing is, it looks to me like you could do something like...

class LocationFromJson {
    public LocationContentsFromJson First;
}

class LocationContentsFromJson {
    public string cafeID, cafeName, cafeState, cafeCity, cafeStreetName, cafeZip;
}


//Later usage; this should be equivalent to your example:
var deserialisedJson = JsonConvert.DeserializeObject<LocationFromJson[][][][]>(json);

var locations = 
    deserialisedJson //4 levels of enumerable
        .SelectMany(o => o) //3 levels of enumerable
        .SelectMany(o => o) //2 levels of enumerable
        .SelectMany(o => o) //1 level of enumerable
        .Select(o => new Location {
            CafeId = o.First.cafeID,
            CafeName = o.First.cafeName,
            CafeState = o.First.cafeState,
            CafeCity = o.First.cafeCity,
            CafeStreetName = o.First.cafeStreetName,
            CafeZip = o.First.cafeZip,
        }).ToArray();

To be explicit: this may or may not work unaltered. Your example does not include the type declaration of Location nor an example json, so I'm speculating here a little: Location.CafeId might also be an int; I can't tell from your question.

But this shouldn't be too far from what you need.

Eamon Nerbonne
  • 47,023
  • 20
  • 101
  • 166