skip to Main Content

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":[
         
      ]
   },
   "054139ba17b8fdd8df1538e1857c45240d5c9368":[
      
   ]
}

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.

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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();
    

    UPDATE

    This is a version without using "rd" property name

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

    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": []
      }
    ]
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search