使用newtonsoft.json将不同的项反序列化为对象列表

uz75evzq  于 2023-01-27  发布在  其他
关注(0)|答案(2)|浏览(141)

我正在尝试反序列化一个json对象中的不同项。挣扎着如何基于下面的响应创建一个对象。

{
   "a374e91a9f513c79a8961de7c494cf799bbdb35b":{
      "rd":[
         {
            "1":{
               "filename":"The Lion King (2019) BluRay 1080p x264 (nItRo)-XpoZ.mkv",
               "filesize":1819821931
            }
         }
      ]
   },
   "e999ddbb3e18613476546684e34a4a6b0cfec878":{
      "rd":[
         {
            "1":{
               "filename":"The.Lion.King.2019.1080p.BluRay.10bit.x265-HazMatt.mkv",
               "filesize":4256678521
            }
         }
      ]
   },
   "8bb877768a0780c9694767a655720927e6cda57e":{
      "rd":[]
   }
}

我想把它Map到下面的C#结构

var items = JsonConvert.DeserializeObject<List<Item>>(jsonResponse);

Public class Item
{
   public string Key {get; set;} // Example a374e91a9f513c79a8961de7c494cf799bbdb35b
   
   public List<Files> Files {get; set;}

}

Public class File
{
    public string Id{get; set;} // "1"
    public string FileName {get; set;} // The Lion King (2019) BluRay 1080p x264 (nItRo)-XpoZ.mkv
    public long FileSize {get; set:} // 1819821931
}
    • 更新**

注意,"rd"属性名称不是固定的字符串,它也可以有不同的值。

wixjitnu

wixjitnu1#

当你有一个JSON对象带有只在运行时使用的JSON属性名,比如"a374e91a9f513c79a8961de7c494cf799bbdb35b""1",你应该反序列化到字典中。[1]
具体来说,为内部对象定义一个类,该类具有静态Rd属性,如下所示:

public record Item ([property: JsonProperty("rd")] List<Dictionary<string, File>> Rd);

(Here为了简洁起见,我使用record,但您也可以使用更传统的class样式。)
现在您可以执行以下操作:

var root = JsonConvert.DeserializeObject<Dictionary<string, Item>>(json);

您还应该从File中删除Id,因为文件ID将是字典键:

public class File
{
    public string FileName {get; set;} // The Lion King (2019) BluRay 1080p x264 (nItRo)-XpoZ.mkv
    public long FileSize {get; set;} // 1819821931
}

演示小提琴here

    • 更新**
  • "rd"本身不是一个固定的字符串,它也可以有不同的值。*

在这种情况下,消除Item并反序列化为Dictionary<string, Dictionary<string, List<Dictionary<string, File>>>>

var root = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, List<Dictionary<string, File>>>>>(json);

演示小提琴#2 here
[1]参见this answer通过Jon Skeet到 * Deserializing JSON with unknown object names *。

zwghvu4y

zwghvu4y2#

如果你想把JSON数据Map到你的类,你必须首先解析JSON,然后把它转换成你需要的类

List<Item> items = JObject.Parse(json).Properties()
.Select(jo => new Item
{
    Key = jo.Name,
    Files = jo.Value["rd"].Select(ja => ((JObject)ja)).Properties()
    .Select(p => new File
    {
        Id = p.Name,
        FileName = (string)p.Value["filename"],
        FileSize = (long)p.Value["filesize"]
    }).ToList()
}).ToList();

更新
这是未使用“rd”属性名称的版本

List<Item> items = JObject.Parse(json).Properties()
   .Select(jo => new Item
   {
       Key = jo.Name,
       Files = new JObject(((JObject)jo.Value)
   .Properties().First()).Properties().First().Value
   .SelectMany(v => ((JObject)v).Properties()
   .Select(i => new File
   {
       Id = i.Name,
       FileName = (string)i.Value["filename"],
       FileSize = (long)i.Value["filesize"]
   })).ToList()
   }).ToList();

输出

[
  {
    "Key": "a374e91a9f513c79a8961de7c494cf799bbdb35b",
    "Files": [
      {
        "Id": "1",
        "FileName": "The Lion King (2019) BluRay 1080p x264 (nItRo)-XpoZ.mkv",
        "FileSize": 1819821931
      }
    ]
  },
  {
    "Key": "e999ddbb3e18613476546684e34a4a6b0cfec878",
    "Files": [
      {
        "Id": "1",
        "FileName": "The.Lion.King.2019.1080p.BluRay.10bit.x265-HazMatt.mkv",
        "FileSize": 4256678521
      }
    ]
  },
  {
    "Key": "8bb877768a0780c9694767a655720927e6cda57e",
    "Files": []
  }
]

相关问题