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

我真的不知道还能做什么。。如有任何帮助,我们将不胜感激。

Newtonsoft反序列化从Collection<;项目>;

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