在C#中反序列化嵌套的匿名JSON

时间:2017-03-11 10:33:14

标签: c# json serialization nested anonymous

我无法弄清楚如何反序列化这个JSON。第一个嵌套对象总是在变化。每次我尝试运行代码时都会导致错误。我盯着Newtonsofts匿名样本,只是无法破译如何在这里使用它。

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

我正在尝试使用Newtonsoft.Json,但我对其他选项持开放态度。 我已经创建了这些类来阅读代码:

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; }
}

然后我尝试用这段代码调用它:

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

我读过很多关于JavaSerialize和Joption以及JSON.net的帖子,但找不到任何有效的解决方案。 这个任务不可能吗?

2 个答案:

答案 0 :(得分:2)

您可以使用JObject解析它(虽然您不会有强类型)并使用合并从中提取值。例如:

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() ?? "";
    }
}

如果您迫切需要输入它们,您甚至可以手动构建对象(尽管是一个子集): - )

答案 1 :(得分:0)

在LINQ方向插上几个小时后,gplumb建议。我有一个工作的反序列化脚本。基本上我必须使用JOption来创建单个子对象,然后操纵子字符串才能使用,然后反序列化为类。
很有趣!

以下是代码:

$('input[type="checkbox"]').change(function() {

    if (this.checked) {
                $(this).next('label').removeClass("icon");
                $(this).next('label').addClass("icon-active");
                $(this).next('label').detach().appendTo('#side');
    }
 else 
    {      // This condition not working //
                $(this).next('label').addClass("icon");
                $(this).next('label').removeClass("icon-active");
                $(this).next('label').appendTo('#main');
    }
});