bertt
bertt

Reputation: 447

Deserialize json object with dynamic items in C#

I've got the following json document:

{
  "name": "bert",
  "Bikes": {
    "Bike1": {
      "value": 1000,
      "type": "Trek"
    },
    "Bike2": {
      "value": 2000,
      "type": "Canyon"
    }
  }
}

With potentially other bikes like Bike3...BikeN. I want to deserialize to C# objects. Problem is that in the deserialization step the bikes data is completely lost, resulting in a null Bikes collection.

Code to reproduce:

[Test]
public void FirstCityJsonParsingTest()
{
    var file = @"./testdata/test.json";
    var json = File.ReadAllText(file);

    var res = JsonConvert.DeserializeObject<Person>(json);
    Assert.IsTrue(res.Name == "bert");
    // next line is failing, because res.Bikes is null...
    Assert.IsTrue(res.Bikes.Count == 2);
}

public class Bike
{
    public string Id { get; set; }
    public int Value { get; set; }
    public string Type { get; set; }
}

public class Person
{
    public string Name { get; set; }
    public List<Bike> Bikes { get; set; }
}

To fix this problem a change in the used model is necessary. But what change is needed here to fill the bikes data correctly?

Note: Changing the input document is not an option (as it's a spec)

Upvotes: 3

Views: 235

Answers (1)

Guru Stron
Guru Stron

Reputation: 143483

Your code structure is not reflecting your json. Common approach to deserializing json with dynamic property names is to use Dictionary<string, ...> (supported both by Json.NET and System.Text.Json). Try the following:

public class Bike
{
    public int Value { get; set; }
    public string Type { get; set; }
}

public class Person
{
    public string Id { get; set; }
    public string Name { get; set; }
    public Dictionary<string, Bike> Bikes { get; set; }
}

Person.Bikes should be changed to Dictionary<string, Bike> (also Bike.Id property is not needed) cause Bikes json element is not an array but object.

Upvotes: 7

Related Questions