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

Deserialize Nested Anonymous JSON in C#

我不知道如何反序列化这个 JSON。第一个嵌套对象总是在变化。每次我尝试 运行 代码时,这都会导致错误。我一直盯着 Newtonsofts Anonymous 样本看,只是无法理解如何在此处使用它。

{
    "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 的帖子,但找不到任何有效的解决方案。 这个任务不可能完成吗?

您可以使用 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() ?? "";
    }
}

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

在 gplumb 推荐的 LINQ 方向上投入了几个小时之后。我有一个有效的反序列化脚本。基本上我必须使用 JOption 来分割出各个子对象,然后操纵子字符串以使其可用,然后反序列化为 class.
很有趣!

代码如下:

    //Polling response from URL
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    StreamReader resStream = new StreamReader(response.GetResponseStream());

    //Parsing response to separate out each donation
    JObject ParsedJson = JObject.Parse(resStream.ReadToEnd());
    var TransactionArray = ParsedJson["donations"].Children();

    //Array to store parsed results into usable format
    List<DonationsJSON> TransArray = new List<DonationsJSON> { };
    foreach (object Transaction in TransactionArray)
    {
        // clean up parsed string and remove Anonymous ID string
        string DonationString = Transaction.ToString().Replace("\r\n", "");
        DonationString = DonationString.Substring(DonationString.IndexOf(':') + 1);

        // Deserializing string into Donation class and adding to List
        DonationsJSON TX = JsonConvert.DeserializeObject<DonationsJSON>(DonationString);
        TransArray.Add(TX);
    }