Newtonsoft反序列化从Collection<;项目>;
本文关键字:项目 gt 反序列化 lt Collection Newtonsoft | 更新日期: 2023-09-27 17:59:11
我正在尝试使用NewtonSoft.Json反序列化程序,但我不知道我尝试做的是否可行,因为我看到的每个集合示例都是这样的:
public class ItemRecords
{
public List<ItemRecords> Items { get; set; }
...
}
我想要的是如下所述的东西。。。
我有两个班:
public class ItemRecords : Collection<ItemRecord>
{
[JsonProperty("property1")]
public int Property1 { get; set; }
[JsonProperty("property2")]
public int Property2 { get; set; }
}
public class ItemRecord
{
[JsonProperty("id")]
public int Id { get; set; }
[JsonProperty("item_prop1")]
public string ItemProp1 { get; set; }
...
}
我从我的api得到这个json:
{
property1: 25,
property2: 27,
item_record: [
{
id: 241,
item_prop1: "0.132",
item_prop2: "78787",
...
},
{
id: 242
item_prop1: "1212",
item_prop2: "3333",
...
}
...
]
}
ItemRecords是ItemRecord的集合
我尝试将JsonArray属性添加到ItemRecords类中,如下所示:
[JsonArray(ItemConverterType = typeof(ItemRecord))]
public class ItemRecords : Collection<ItemRecord> { ... }
以下是执行请求的方法:
private static async Task<T> MakeRequest<T>(string urlRequest)
{
try
{
HttpWebRequest request = WebRequest.Create(urlRequest) as HttpWebRequest;
using (WebResponse response = await request.GetResponseAsync())
{
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream);
string line = string.Empty;
StringBuilder sb = new StringBuilder();
while ((line = reader.ReadLine()) != null)
{
sb.Append(line);
}
T objectDeserialized = JsonConvert.DeserializeObject<T>(sb.ToString());
return objectDeserialized;
}
}
}
catch (Exception ex)
{
return default(T);
}
}
对这个方法的调用如下:
...
return await MakeRequest<ItemRecords>(request);
我真的不知道还能做什么。。如有任何帮助,我们将不胜感激。
JSON标准有两种类型的容器:
-
对象是一组无序的名称/值对。对象以
{
(左大括号)开始,以}
(右大括号)结束。Json.NET默认情况下将字典和不可枚举的POCOS映射到对象,使用反射将c#属性映射到Json属性。在您从API返回的JSON中,最外层的容器是一个对象。
-
数组,它是值的有序集合。数组以
[
(左括号)开始,以]
(右括号)结束。值用,
(逗号)分隔。Json.NET默认情况下将非字典枚举映射到数组,将每个集合项序列化为数组项。在您从API返回的JSON中,
item_record
属性的值是一个数组。
作为一个具有属性的集合,ItemRecords
不能在不丢失数据的情况下自动映射到这两个构造中的任何一个。由于Json.NET默认情况下将集合序列化为数组,因此您需要通过应用[JsonObject]
属性手动通知它您的类型将被序列化为对象。然后,引入一个合成的item_record
属性来序列化和反序列化集合项。由于您继承自Collection<T>
,因此可以将Collection<T>.Items
用于此目的:
[JsonObject(MemberSerialization.OptIn)]
public class ItemRecords : Collection<ItemRecord>
{
[JsonProperty("property1")]
public int Property1 { get; set; }
[JsonProperty("property2")]
public int Property2 { get; set; }
[JsonProperty("item_record")]
IList<ItemRecord> ItemRecordList
{
get
{
return Items;
}
}
}
使用MemberSerialization.OptIn
可以防止诸如Count
之类的基类属性被序列化。
样品小提琴。
顺便说一句,我并不特别推荐这种设计,因为它可能会导致其他序列化程序出现问题。例如,XmlSerializer
永远不会序列化集合属性;看这儿或这儿。另请参阅为什么不从列表继承?。
只需将List<ItemRecord> Records
属性添加到类ItemRecords
:
public class ItemRecords
{
[JsonProperty("property1")]
public int Property1 { get; set; }
[JsonProperty("property2")]
public int Property2 { get; set; }
[JsonProperty("item_record")]
public List<ItemRecord> Records { get; set; }
}
这看起来像是你可以有一个动态数量的属性和项目属性的结果,比如:
{
property1: 25,
property2: 27,
property3: 30,
item_record: [
{
id: 241,
item_prop1: "0.132",
item_prop2: "78787"
},
{
id: 242
item_prop1: "1212",
item_prop2: "3333",
item_prop3: "3333",
item_prop4: "3333",
}
] }
如果是这样的话,在我看来,最好的选择是将结构更改为类似
{
properties:[
25,
27,
30
],
itemRecords:[
{
id: 27,
itemProperties:[
"321",
"654",
"564"
]
},
{
id: 25,
itemProperties:[
"321",
"654"
]
},
]
}