Stanton Stanton - 9 months ago 49
C# Question

Deserialize Nested Anonymous JSON in C#

I cannot figure out how to deserialize this JSON. The first nested object is always changing. This causes an error every time I try to run the code. I've stared at Newtonsofts Anonymous samples and just can't decipher how to use it here.

{
"donations" : {
"5859453c0a2c0b777ee6b686" : {
"id" : "5859453c0a2c0b777ee6b686",
"package" : {
"_id" : {
"$oid" : "5833a3580a2c0b40ec7c9c9a"
},
"channel_perks" : [{
"viewer_points" : 10
}, {
"mysterybag" : 2
}
],
},
"updated_at" : "2016-12-20T14:50:36.996Z"
},
"585c18c60a2c0b02b189ac7a" : {
"package" : {
"_id" : {
"$oid" : "585988a50a2c0b777ee6bc0e"
},
"channel_perks" : [{
"viewer_points" : 10
}, {
"slap" : 2
}
],
},
"updated_at" : "2016-12-22T18:17:42.690Z"
},
"585e9e240a2c0b02b189b3e2" : {
"id" : "585e9e240a2c0b02b189b3e2",
"package" : {
"_id" : {
"$oid" : "585988a50a2c0b777ee6bc11"
},
"channel_perks" : [{
"viewer_points" : 100
}, {
"slap" : 35
}, {
"mysterybag" : 30
}
],
},
"updated_at" : "2016-12-24T16:11:17.021Z"
},
},
}


I'm attempting to use Newtonsoft.Json but I'm open to other options.
I've created these classes to read the code:

class APIResponse
{
public DonationID donations { get; set; }
}
class DonationID
{
public DonationJSON id { get; set; }
}
class DonationJSON
{
public string id { get; set; }
public PackageJSON package { get; set; }
public string updated_at { get; set; }
}

class PackageJSON
{
public PackageID _id { get; set; }
public List<ChannelPerks> channel_perks { get; set; }
}
class PackageID
{
[JsonProperty(PropertyName = "$oid")]
public string oid { get; set; }
}
class ChannelPerks
{
public string viewer_points { get; set; }
public string mysterybag { get; set; }
public string slap { get; set; }
}


Then I try to call it with this code:

var definition = new APIResponse();
var data = JsonConvert.DeserializeAnonymousType(JSONDATA, definition);


I've read many posts about JavaSerialize and Joption as well as JSON.net, but can't find any solution that works.
Is this task impossible?

Answer Source

You could parse it using JObject (although you won't have strong typing) and use coalescence to extract values out of it. For example:

using (var stream = new FileStream(path, FileMode.Open))
{
    using (var reader = new StreamReader(stream))
    {
        string data = reader.ReadToEnd();
        var json = JObject.Parse(data);

        var donationId = json?["donations"]?["5859453c0a2c0b777ee6b686"]?["id"]?.ToString() ?? "";
    }
}

You could even build up your objects manually (albeit as a subset) if you desperately needed them to be typed :-)