-Fixed passing default values to constructors
This commit is contained in:
@@ -24,7 +24,10 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Newtonsoft.Json.Tests.TestObjects;
|
||||
#if NETFX_CORE
|
||||
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
|
||||
@@ -37,6 +40,11 @@ using Assert = Newtonsoft.Json.Tests.XUnitAssert;
|
||||
#else
|
||||
using NUnit.Framework;
|
||||
#endif
|
||||
#if NET20
|
||||
using Newtonsoft.Json.Utilities.LinqBridge;
|
||||
#else
|
||||
using System.Linq;
|
||||
#endif
|
||||
|
||||
namespace Newtonsoft.Json.Tests.Serialization
|
||||
{
|
||||
@@ -162,5 +170,79 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
Assert.IsNotNull(c);
|
||||
Assert.AreEqual(1, c.Name);
|
||||
}
|
||||
|
||||
public class ConstructorParametersRespectDefaultValueAttributes
|
||||
{
|
||||
[DefaultValue("parameter1_default")]
|
||||
public string Parameter1 { get; private set; }
|
||||
[DefaultValue("parameter2_default")]
|
||||
public string Parameter2 { get; private set; }
|
||||
[DefaultValue("parameter3_default")]
|
||||
public string Parameter3 { get; set; }
|
||||
[DefaultValue("parameter4_default")]
|
||||
public string Parameter4 { get; set; }
|
||||
|
||||
public ConstructorParametersRespectDefaultValueAttributes(string parameter1, string parameter2, string parameter3)
|
||||
{
|
||||
Parameter1 = parameter1;
|
||||
Parameter2 = parameter2;
|
||||
Parameter3 = parameter3;
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConstructorParametersRespectDefaultValueTest_Attrbutes()
|
||||
{
|
||||
var testObject = JsonConvert.DeserializeObject<ConstructorParametersRespectDefaultValueAttributes>("{'Parameter2':'value!'}", new JsonSerializerSettings()
|
||||
{
|
||||
DefaultValueHandling = DefaultValueHandling.Populate
|
||||
});
|
||||
|
||||
Assert.AreEqual("parameter1_default", testObject.Parameter1);
|
||||
Assert.AreEqual("value!", testObject.Parameter2);
|
||||
Assert.AreEqual("parameter3_default", testObject.Parameter3);
|
||||
Assert.AreEqual("parameter4_default", testObject.Parameter4);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConstructorParametersRespectDefaultValueTest()
|
||||
{
|
||||
var testObject = JsonConvert.DeserializeObject<ConstructorParametersRespectDefaultValue>("{}", new JsonSerializerSettings() { ContractResolver = ConstructorParameterDefaultStringValueContractResolver.Instance });
|
||||
|
||||
Assert.AreEqual("Default Value", testObject.Parameter1);
|
||||
Assert.AreEqual("Default Value", testObject.Parameter2);
|
||||
}
|
||||
|
||||
public class ConstructorParametersRespectDefaultValue
|
||||
{
|
||||
public const string DefaultValue = "Default Value";
|
||||
|
||||
public string Parameter1 { get; private set; }
|
||||
public string Parameter2 { get; private set; }
|
||||
|
||||
public ConstructorParametersRespectDefaultValue(string parameter1, string parameter2)
|
||||
{
|
||||
Parameter1 = parameter1;
|
||||
Parameter2 = parameter2;
|
||||
}
|
||||
}
|
||||
|
||||
public class ConstructorParameterDefaultStringValueContractResolver : DefaultContractResolver
|
||||
{
|
||||
public static new ConstructorParameterDefaultStringValueContractResolver Instance = new ConstructorParameterDefaultStringValueContractResolver();
|
||||
|
||||
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
|
||||
{
|
||||
var properties = base.CreateProperties(type, memberSerialization);
|
||||
|
||||
foreach (var property in properties.Where(p => p.PropertyType == typeof(string)))
|
||||
{
|
||||
property.DefaultValue = ConstructorParametersRespectDefaultValue.DefaultValue;
|
||||
property.DefaultValueHandling = DefaultValueHandling.Populate;
|
||||
}
|
||||
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,17 +309,20 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
Assert.AreEqual(new DateTime(2000, 12, 1, 0, 0, 0, DateTimeKind.Utc), c[2]);
|
||||
|
||||
Assert.AreEqual(3, errors.Count);
|
||||
#if !(NET20 || NET35)
|
||||
var possibleErrs = new [] {
|
||||
#if !(NET20 || NET35)
|
||||
"[1] - 1 - The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.",
|
||||
"[1] - 1 - String was not recognized as a valid DateTime."
|
||||
#else
|
||||
// handle typo fix in later versions of .NET
|
||||
"[1] - 1 - The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.",
|
||||
"[1] - 1 - The string was not recognized as a valid DateTime. There is a unknown word starting at index 0."
|
||||
#endif
|
||||
};
|
||||
|
||||
Assert.IsTrue(possibleErrs.Any (m => m == errors[0]),
|
||||
"Expected One of: " + string.Join (Environment.NewLine, possibleErrs) + Environment.NewLine + "But was: " + errors[0]);
|
||||
#else
|
||||
Assert.AreEqual("[1] - 1 - The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.", errors[0]);
|
||||
#endif
|
||||
|
||||
Assert.AreEqual("[2] - 2 - Unexpected token parsing date. Expected String, got StartArray. Path '[2]', line 4, position 10.", errors[1]);
|
||||
Assert.AreEqual("[4] - 4 - Cannot convert null value to System.DateTime. Path '[4]', line 8, position 13.", errors[2]);
|
||||
}
|
||||
|
||||
@@ -92,13 +92,13 @@
|
||||
<Compile Include="JsonDictionaryAttribute.cs" />
|
||||
<Compile Include="JsonException.cs" />
|
||||
<Compile Include="JsonExtensionDataAttribute.cs" />
|
||||
<Compile Include="JsonRequiredAttribute.cs" />
|
||||
<Compile Include="JsonIgnoreAttribute.cs" />
|
||||
<Compile Include="JsonObjectAttribute.cs" />
|
||||
<Compile Include="JsonPosition.cs" />
|
||||
<Compile Include="JsonPropertyAttribute.cs" />
|
||||
<Compile Include="JsonReader.cs" />
|
||||
<Compile Include="JsonReaderException.cs" />
|
||||
<Compile Include="JsonRequiredAttribute.cs" />
|
||||
<Compile Include="JsonSerializationException.cs" />
|
||||
<Compile Include="JsonSerializer.cs" />
|
||||
<Compile Include="JsonSerializerSettings.cs" />
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
foreach (JsonProperty property in Properties)
|
||||
{
|
||||
if (property.Required != Required.Default || ((property.DefaultValueHandling & DefaultValueHandling.Populate) == DefaultValueHandling.Populate) && property.Writable)
|
||||
if (property.Required != Required.Default || (property.DefaultValueHandling & DefaultValueHandling.Populate) == DefaultValueHandling.Populate)
|
||||
{
|
||||
_hasRequiredOrDefaultValueProperties = true;
|
||||
break;
|
||||
|
||||
@@ -1662,6 +1662,34 @@ namespace Newtonsoft.Json.Serialization
|
||||
}
|
||||
}
|
||||
|
||||
// handle giving default values to creator parameters
|
||||
// this needs to happen before the call to creator
|
||||
if (propertiesPresence != null)
|
||||
{
|
||||
foreach (KeyValuePair<JsonProperty, PropertyPresence> propertyPresence in propertiesPresence)
|
||||
{
|
||||
JsonProperty property = propertyPresence.Key;
|
||||
PropertyPresence presence = propertyPresence.Value;
|
||||
|
||||
if (!property.Ignored && (presence == PropertyPresence.None || presence == PropertyPresence.Null))
|
||||
{
|
||||
if (property.PropertyContract == null)
|
||||
property.PropertyContract = GetContractSafe(property.PropertyType);
|
||||
|
||||
if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate))
|
||||
{
|
||||
// have to use the name because property presence doesn't use creator properties
|
||||
int i = contract.CreatorParameters.IndexOf(p => p.PropertyName == property.PropertyName);
|
||||
|
||||
if (i != -1)
|
||||
{
|
||||
creatorParameterValues[i] = EnsureType(reader, property.GetResolvedDefaultValue(), CultureInfo.InvariantCulture, property.PropertyContract, property.PropertyType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object createdObject = creator(creatorParameterValues);
|
||||
|
||||
if (id != null)
|
||||
|
||||
Reference in New Issue
Block a user