-Fixed DefaultValueHandling Populate bug

This commit is contained in:
James Newton-King
2012-09-01 15:23:17 +12:00
parent 2320d2d55e
commit 0714c05e6f
5 changed files with 109 additions and 7 deletions
@@ -228,6 +228,81 @@ namespace Newtonsoft.Json.Tests.Serialization
""IntDefault"": 0
}", json);
}
[Test]
public void DeserializeWithIgnore()
{
string json = @"{'Value':null,'IntValue1':1,'IntValue2':0,'IntValue3':null}";
var o = JsonConvert.DeserializeObject<DefaultValueHandlingDeserializeHolder>(json, new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.Ignore
});
Assert.AreEqual(int.MaxValue, o.IntValue1);
Assert.AreEqual(int.MinValue, o.IntValue2);
Assert.AreEqual(int.MaxValue, o.IntValue3);
Assert.AreEqual("Derp!", o.ClassValue.Derp);
}
[Test]
public void DeserializeWithPopulate()
{
string json = @"{}";
var o = JsonConvert.DeserializeObject<DefaultValueHandlingDeserializePopulate>(json, new JsonSerializerSettings
{
DefaultValueHandling = DefaultValueHandling.Populate
});
Assert.AreEqual(1, o.IntValue1);
Assert.AreEqual(0, o.IntValue2);
Assert.AreEqual(null, o.ClassValue);
}
}
public class DefaultValueHandlingDeserialize
{
public string Derp { get; set; }
}
public class DefaultValueHandlingDeserializeHolder
{
public DefaultValueHandlingDeserializeHolder()
{
ClassValue = new DefaultValueHandlingDeserialize
{
Derp = "Derp!"
};
IntValue1 = int.MaxValue;
IntValue2 = int.MinValue;
IntValue3 = int.MaxValue;
}
[DefaultValue(1)]
public int IntValue1 { get; set; }
public int IntValue2 { get; set; }
[DefaultValue(null)]
public int IntValue3 { get; set; }
public DefaultValueHandlingDeserialize ClassValue { get; set; }
}
public class DefaultValueHandlingDeserializePopulate
{
public DefaultValueHandlingDeserializePopulate()
{
ClassValue = new DefaultValueHandlingDeserialize
{
Derp = "Derp!"
};
IntValue1 = int.MaxValue;
IntValue2 = int.MinValue;
}
[DefaultValue(1)]
public int IntValue1 { get; set; }
public int IntValue2 { get; set; }
public DefaultValueHandlingDeserialize ClassValue { get; set; }
}
public struct DefaultStruct
@@ -471,7 +471,10 @@ namespace Newtonsoft.Json.Serialization
property.PropertyName = (property.PropertyName != parameterInfo.Name) ? property.PropertyName : matchingMemberProperty.PropertyName;
property.Converter = property.Converter ?? matchingMemberProperty.Converter;
property.MemberConverter = property.MemberConverter ?? matchingMemberProperty.MemberConverter;
property.DefaultValue = property.DefaultValue ?? matchingMemberProperty.DefaultValue;
if (!property._hasExplicitDefaultValue && matchingMemberProperty._hasExplicitDefaultValue)
property.DefaultValue = matchingMemberProperty.DefaultValue;
property._required = property._required ?? matchingMemberProperty._required;
property.IsReference = property.IsReference ?? matchingMemberProperty.IsReference;
property.NullValueHandling = property.NullValueHandling ?? matchingMemberProperty.NullValueHandling;
@@ -1011,7 +1014,8 @@ namespace Newtonsoft.Json.Serialization
property.MemberConverter = JsonTypeReflector.GetJsonConverter(attributeProvider, property.PropertyType);
DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute<DefaultValueAttribute>(attributeProvider);
property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null;
if (defaultValueAttribute != null)
property.DefaultValue = defaultValueAttribute.Value;
property.NullValueHandling = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null;
property.ReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null;
@@ -24,6 +24,8 @@
#endregion
using System;
using Newtonsoft.Json.Utilities;
#if NET20
using Newtonsoft.Json.Utilities.LinqBridge;
#endif
@@ -36,6 +38,8 @@ namespace Newtonsoft.Json.Serialization
public class JsonProperty
{
internal Required? _required;
internal bool _hasExplicitDefaultValue;
internal object _defaultValue;
// use to cache contract during deserialization
internal JsonContract PropertyContract { get; set; }
@@ -117,7 +121,26 @@ namespace Newtonsoft.Json.Serialization
/// Gets the default value.
/// </summary>
/// <value>The default value.</value>
public object DefaultValue { get; set; }
public object DefaultValue
{
get
{
return _defaultValue;
}
set
{
_hasExplicitDefaultValue = true;
_defaultValue = value;
}
}
internal object GetResolvedDefaultValue()
{
if (!_hasExplicitDefaultValue && PropertyType != null)
return ReflectionUtils.GetDefaultValue(PropertyType);
return _defaultValue;
}
/// <summary>
/// Gets a value indicating whether this <see cref="JsonProperty"/> is required.
@@ -737,7 +737,7 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
// test tokentype here because default value might not be convertable to actual type, e.g. default of "" for DateTime
if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore)
&& JsonReader.IsPrimitiveToken(reader.TokenType)
&& MiscellaneousUtils.ValueEquals(reader.Value, property.DefaultValue))
&& MiscellaneousUtils.ValueEquals(reader.Value, property.GetResolvedDefaultValue()))
{
reader.Skip();
return true;
@@ -772,7 +772,7 @@ To fix this error either change the JSON to a {1} or change the deserialized typ
return false;
if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore)
&& MiscellaneousUtils.ValueEquals(value, property.DefaultValue))
&& MiscellaneousUtils.ValueEquals(value, property.GetResolvedDefaultValue()))
return false;
if (!property.Writable)
@@ -1572,7 +1572,7 @@ To fix this error either change the environment to be fully trusted, change the
property.PropertyContract = GetContractSafe(property.PropertyType);
if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Populate) && property.Writable)
property.ValueProvider.SetValue(newObject, EnsureType(reader, property.DefaultValue, CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType));
property.ValueProvider.SetValue(newObject, EnsureType(reader, property.GetResolvedDefaultValue(), CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType));
break;
case PropertyPresence.Null:
if (resolvedRequired == Required.Always)
@@ -205,7 +205,7 @@ namespace Newtonsoft.Json.Serialization
return false;
if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer.DefaultValueHandling), DefaultValueHandling.Ignore)
&& MiscellaneousUtils.ValueEquals(memberValue, property.DefaultValue ?? ReflectionUtils.GetDefaultValue(property.PropertyType)))
&& MiscellaneousUtils.ValueEquals(memberValue, property.GetResolvedDefaultValue()))
return false;
return true;