在 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);
}
我不知道如何反序列化这个 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);
}