Description
Background and Motivation
Both the XmlSerializer and @JamesNK 's JSON.Net support the convention that whether a property on a class (say property XYZ) should be serialized or has been deserialized can be controlled/reported through a second property on the class (which is named by convention as XYZSpecified).
See
This allows any code working with the deserialized data to tell the difference between a property that has a default value because the source document didn't have a value, and a document that did have a value but it happened to equal the default value. It also allows any code working with the serializer to optionally decide whether a particular property should be serialized or not (at run time).
This is extremely useful when trying to make an API backwards compatible. Say you add a property "NumberOfChildren" to a"Person" class. New client applications will send in values for how many children the person has, but old client applications won't. However, if your code cannot tell the difference between a new client application setting the property to zero and an old client just not sending the data at all, you could mistakenly overwrite the NumberOfChildren value stored in your database.
Proposed API
Please have System.Text.Json allow the calling code to optionally (at runtime) decide whether a particular property should be serialized or not on an object by object basis. Also allow the calling code to be able to tell if a property's value is set because it was deserialised or because it is the default value for the property.
Usage Examples
During serialization:
SpecifiedTestClass` c = new SpecifiedTestClass();
c.Name = "James";
c.Age = 27;
c.NameSpecified = false;
var json = JsonSerializer.Serialize(c);
StringAssert.AreEqual(@"{
""Age"": 27
}", json);
During deserialization:
string mikeFullDisclosureString = "{\"Name\": \"Mike Person\", \"NumberOfChildren\": \"0\"}";
var mike = JsonSerializer.Deserialize<FamilyDetails>(mikeFullDisclosureString);
Assert.AreEqual(true, mike.NumberOfChildrenSpecified);
Alternative Designs
Maybe tere is already a way to achieve this that I have missed.
Risks
Performance overhead of looking for "Specified" properties. Also, most "Specified" properties need to be ignored either by using the JsonIgnore or a convention to ignore them.