0

Assuming I have an array of the following JSON data:

[
  {
    "foo": "somestring",
    "foo1": 2,
    "foo2": [
      "somestring1",
      "somestring2"
    ],
    "foo3": [
      {
        "bar1": 122312,
        "bar2": 3214324
      },
      {
        "bar3": 432432432,
        "bar4": 4324231
      }
    ]
  },
//more root array members...
]

I have created the following classes for the JSON to be deserialized into:

internal class StoredFoo
{
    [JsonPropertyName("foo")]
    public string Foo
    {
        get; set;
    }

    [JsonPropertyName("foo1")]
    public double Foo1
    {
        get; set;
    }
    [JsonPropertyName("foo2")]
    public List<string> Foo2 { get; } = new List<string>();
    [JsonPropertyName("foo3")]
    public List<StoredBar> Foo3 { get; } = new List<StoredBar>();
}

internal class StoredBar
{
    [JsonPropertyName("bar1")]
    public long Bar1
    {
        get; set;
    }

    [JsonPropertyName("bar2")]
    public long Bar2
    {
        get; set;
    }
}    

(I apologize for being unable to use real names. part of the limitations of the project)

When I load up the JSON file and deserialize it:

string jsonFooData = File.ReadAllText(filePath);
IEnumerable<Foo> storedFoos = JsonSerializer.Deserialize<IEnumerable<Foo>>(jsonFooData);

Then storedFoos contains the objects, but Foo2 and Foo3 are empty, even when they shouldn't.

At first, I thought that this is because somehow the = new List<string>() occurs after the JsonSerializer had initialized the collection, effectively overriding it. But even removing the = new List<string>() statement, the collections are just set to null (without exception).

Why is that that JsonSerializer succeeds in deserializing into foo and foo1 but not foo2 and foo3?

Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Aviv Vetaro
  • 363
  • 5
  • 12
  • 5
    Your `Foo2` and `Foo3` are get only properties so they are never initialised. Change them to be `get; set;` like the others – zaitsman Aug 03 '21 at 06:50

1 Answers1

0

As @zaitsman suggested, we can change the properties to be mutable.

If we want to populate read-only properties, we can use a public constructor.

public class StoredFoo
{
    [JsonPropertyName("foo")]
    public string Foo { get; set; }

    [JsonPropertyName("foo1")]
    public double Foo1 { get; set; }

    [JsonPropertyName("foo2")]
    public List<string> Foo2 { get; } = new List<string>();

    [JsonPropertyName("foo3")]
    public List<StoredBar> Foo3 { get; } = new List<StoredBar>();

    public StoredFoo(string foo, double foo1, List<string> foo2, List<StoredBar> foo3)
        => (Foo, Foo1, Foo2, Foo3) = (foo, foo1, foo2, foo3);
}

If there is more than one constructor, use the JsonConstructor attribute to define which constructor to use.

Crafted Pod
  • 522
  • 2
  • 5