-Added ItemNullValueHandling to JsonObjectContract

This commit is contained in:
James Newton-King
2017-11-08 16:32:42 +13:00
parent 08ea72b72b
commit fcd5975cd9
6 changed files with 28 additions and 16 deletions
+2 -2
View File
@@ -51,9 +51,9 @@ namespace Newtonsoft.Json
}
/// <summary>
/// Gets or sets the null value handling.
/// Gets or sets how the object's properties with null values are handled during serialization and deserialization.
/// </summary>
/// <value>The null value handling.</value>
/// <value>How the object's properties with null values are handled during serialization and deserialization.</value>
public NullValueHandling ItemNullValueHandling
{
get => _itemNullValueHandling ?? default(NullValueHandling);
@@ -327,6 +327,8 @@ namespace Newtonsoft.Json.Serialization
if (attribute != null)
{
contract.ItemRequired = attribute._itemRequired;
contract.ItemNullValueHandling = attribute._itemNullValueHandling;
if (attribute.NamingStrategyType != null)
{
NamingStrategy namingStrategy = JsonTypeReflector.GetContainerNamingStrategy(attribute);
@@ -1509,11 +1511,6 @@ namespace Newtonsoft.Json.Serialization
#endif
}
if (property.NullValueHandling == null && containerAttribute is JsonObjectAttribute objectAttribute)
{
property.NullValueHandling = objectAttribute._itemNullValueHandling;
}
if (requiredAttribute != null)
{
property._required = Required.Always;
@@ -52,6 +52,12 @@ namespace Newtonsoft.Json.Serialization
/// </value>
public Required? ItemRequired { get; set; }
/// <summary>
/// Gets or sets how the object's properties with null values are handled during serialization and deserialization.
/// </summary>
/// <value>How the object's properties with null values are handled during serialization and deserialization.</value>
public NullValueHandling? ItemNullValueHandling { get; set; }
/// <summary>
/// Gets the object's properties.
/// </summary>
@@ -81,6 +81,16 @@ namespace Newtonsoft.Json.Serialization
}
}
protected NullValueHandling ResolvedNullValueHandling(JsonObjectContract containerContract, JsonProperty property)
{
NullValueHandling resolvedNullValueHandling =
property.NullValueHandling
?? containerContract?.ItemNullValueHandling
?? Serializer._nullValueHandling;
return resolvedNullValueHandling;
}
private ErrorContext GetErrorContext(object currentObject, object member, string path, Exception error)
{
if (_currentErrorContext == null)
@@ -1012,7 +1012,7 @@ namespace Newtonsoft.Json.Serialization
// otherwise also set it if CreateValue returns a new value compared to the currentValue
// this could happen because of a JsonConverter against the type
if ((!useExistingValue || value != currentValue)
&& ShouldSetPropertyValue(property, value))
&& ShouldSetPropertyValue(property, containerContract as JsonObjectContract, value))
{
property.ValueProvider.SetValue(target, value);
@@ -1076,7 +1076,7 @@ namespace Newtonsoft.Json.Serialization
}
// test tokenType here because null might not be convertible to some types, e.g. ignoring null when applied to DateTime
if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && tokenType == JsonToken.Null)
if (tokenType == JsonToken.Null && ResolvedNullValueHandling(containerContract as JsonObjectContract, property) == NullValueHandling.Ignore)
{
return true;
}
@@ -1129,9 +1129,9 @@ namespace Newtonsoft.Json.Serialization
return ((value & flag) == flag);
}
private bool ShouldSetPropertyValue(JsonProperty property, object value)
private bool ShouldSetPropertyValue(JsonProperty property, JsonObjectContract contract, object value)
{
if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && value == null)
if (value == null && ResolvedNullValueHandling(contract, property) == NullValueHandling.Ignore)
{
return false;
}
@@ -1992,7 +1992,7 @@ namespace Newtonsoft.Json.Serialization
JsonProperty property = context.Property;
object value = context.Value;
if (ShouldSetPropertyValue(property, value))
if (ShouldSetPropertyValue(property, contract, value))
{
property.ValueProvider.SetValue(createdObject, value);
context.Used = true;
@@ -270,10 +270,9 @@ namespace Newtonsoft.Json.Serialization
return Serializer.GetReferenceResolver().IsReferenced(this, value);
}
private bool ShouldWriteProperty(object memberValue, JsonProperty property)
private bool ShouldWriteProperty(object memberValue, JsonObjectContract containerContract, JsonProperty property)
{
if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore &&
memberValue == null)
if (memberValue == null && ResolvedNullValueHandling(containerContract, property) == NullValueHandling.Ignore)
{
return false;
}
@@ -525,7 +524,7 @@ namespace Newtonsoft.Json.Serialization
memberValue = property.ValueProvider.GetValue(value);
memberContract = (property.PropertyContract.IsSealed) ? property.PropertyContract : GetContractSafe(memberValue);
if (ShouldWriteProperty(memberValue, property))
if (ShouldWriteProperty(memberValue, contract as JsonObjectContract, property))
{
if (ShouldWriteReference(memberValue, property, memberContract, contract, member))
{