Home > Mobile >  Deserialize different items into a list of objects using newtonsoft.json
Deserialize different items into a list of objects using newtonsoft.json

Time:01-27

I am trying to deserialize different items in a json object. Struggling how to create an object based on the following response.

{
   "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":[]
   }
}

I would like to map it to the following C# structure

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
}

Update

Note that the "rd" property name isn't a fixed string, it can also have different values.

CodePudding user response:

When you have a JSON object with runtime-only JSON property names such as "a374e91a9f513c79a8961de7c494cf799bbdb35b" and "1", you should deserialize to a dictionary.[1]

Specifically, define a class for the inner object that has a static Rd property like so:

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

(Here I am using a record for brevity, but you could just as easily use the more traditional class style.)

And now you can do:

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

You should also remove Id from File since the file ID will be the dictionary key:

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

Demo fiddle here.

Update

"rd" itself isn't a fixed string, it can also have different values.

In that case, eliminate Item and deserialize to Dictionary<string, Dictionary<string, List<Dictionary<string, File>>>>:

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

Demo fiddle #2 here.


[1] See this answer by Jon Skeet to Deserializing JSON with unknown object names.

CodePudding user response:

if you want to map json data to your class you will have to parse json at first, after this to convert it to a class you need

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

output

[
  {
    "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": []
  }
]
  • Related