I'm trying to have a property of an object to return a default value in the absence of that property in the json I deserialize.
I read that I can achieve this using the [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
attribute.
public class MyClass {
public readonly string Id;
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
public RectangleF Position { get; set; } = new RectangleF(0, 0, 1, 1);
[JsonConstructor]
public MyClass(string id, RectangleF position) {
Id = id;
Position = position;
}
}
[Test]
public void DeserializeDefaultValue() {
var json = JObject.FromObject(new { id = "123" });
var obj = json.ToObject<MyClass>();
Expect(obj.Position, Is.EqualTo(new RectangleF(0, 0, 1, 1)));
}
The test fails, with the position always returning a new RectangleF(0, 0, 0, 0)
I can't have a [DefaultValue]
attribute, like I see in a lot of examples, since RectangleF is initialized at runtime.
I tried many things such as having the [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
in the constructor, overloading the constructor with a default value for position, but nothing works.
Is there something simple I'm missing to achieve this?
So I modified what you were doing slightly but this works for what you are trying to accomplish.
public class MyClass
{
public readonly string Id;
public RectangleF Position { get; set; }
[JsonConstructor]
public MyClass(string id, RectangleF? position)
{
Id = id;
Position = position ?? new RectangleF(0, 0, 1, 1);
}
}
Just to add to this, if the only contractor you have assigns any value to a property, the property initializer is ignored (always). If you add a default constructor (with no params) then I believe what you have above will always work.