I have some fairly complex JSON and need to use Newtonsoft to deserialize, as System.Text.Json is not as extensible as Newtonsoft.
My problem is as follows: I have a class, let's call "A", which I use a few places in my app including saving to a DB using EFCore and converting to a binary file. I populate the class using a JSON File, but due to requirements beyond my control I need to keep the default value setter in the class. However, IF the property does NOT exist in the Json we are deserializing, I'd like to use a custom default value.
Example Class:
public class A
{
public int Id { get; set; } = 0;
public bool IsRequired { get; set; } = true;
}
And if this is my Json:
[{
"id": 4,
"isRequired": true;
},
{
"id": 7
}]
I'd like to override the isRequired
default to false if the key is not in the json.
var list = JsonConvert.DeserializeObject<List<A>>( -- some settings --);
// list[0]
// - Id = 4
// - IsRequired = true
//
// list[1]
// - Id = 6
// - IsRequired = false
I've been able to get a basic version of this working as described in this SO post, but the deserialization is very simple and breaks immediately with nested properties and complex types + my custom contract resolver I have.
Note that I am using .NET 6, and my models are separated from my deserializers.
You just can add a json constructor to your class. You don't need to put all properties in the constructor, only those properties that behavier the special way
public class A
{
public int Id { get; set;} = 0;
public bool IsRequired { get; set; } = true;
[JsonConstructor]
public A (bool? isRequired)
{
this.IsRequired = isRequired ?? false;
}
}
test
var list = JsonConvert.DeserializeObject<List<A>>(json);
json=JsonConvert.SerializeObject(list, Newtonsoft.Json.Formatting.Indented);
result
[
{
"Id": 4,
"IsRequired": true
},
{
"Id": 7,
"IsRequired": false
}
]