-Fixed using extension data with a non-default constructor
This commit is contained in:
@@ -604,6 +604,19 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
public IDictionary<object, object> ExtensionData;
|
||||
}
|
||||
|
||||
public class PublicExtensionDataAttributeTestClassWithNonDefaultConstructor
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public PublicExtensionDataAttributeTestClassWithNonDefaultConstructor(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
[JsonExtensionData]
|
||||
public IDictionary<object, object> ExtensionData;
|
||||
}
|
||||
|
||||
public class PublicNoReadExtensionDataAttributeTestClass
|
||||
{
|
||||
public string Name { get; set; }
|
||||
@@ -785,6 +798,34 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
Assert.AreEqual(2m, bizzaroC2.HourlyWage);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DeserializePublicExtensionDataTypeNamdHandlingNonDefaultConstructor()
|
||||
{
|
||||
string json = @"{
|
||||
""$id"": ""1"",
|
||||
""Name"": ""Name!"",
|
||||
""Test"": 1,
|
||||
""Self"": {
|
||||
""$type"": ""Newtonsoft.Json.Tests.TestObjects.WagePerson, Newtonsoft.Json.Tests"",
|
||||
""HourlyWage"": 2.0,
|
||||
""Name"": null,
|
||||
""BirthDate"": ""0001-01-01T00:00:00"",
|
||||
""LastModified"": ""0001-01-01T00:00:00""
|
||||
}
|
||||
}";
|
||||
|
||||
PublicExtensionDataAttributeTestClassWithNonDefaultConstructor c2 = JsonConvert.DeserializeObject<PublicExtensionDataAttributeTestClassWithNonDefaultConstructor>(json, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.Objects
|
||||
});
|
||||
|
||||
Assert.AreEqual("Name!", c2.Name);
|
||||
|
||||
WagePerson bizzaroC2 = (WagePerson)c2.ExtensionData["Self"];
|
||||
|
||||
Assert.AreEqual(2m, bizzaroC2.HourlyWage);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializePublicExtensionDataTypeNamdHandling()
|
||||
{
|
||||
@@ -8715,6 +8756,43 @@ Parameter name: value",
|
||||
Assert.AreEqual("EventName!", values2[0][0, 0].EventName);
|
||||
}
|
||||
|
||||
public class ExtensionDataDeserializeWithNonDefaultConstructor
|
||||
{
|
||||
public ExtensionDataDeserializeWithNonDefaultConstructor(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
[JsonExtensionData]
|
||||
public IDictionary<string, JToken> _extensionData;
|
||||
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExtensionDataDeserializeWithNonDefaultConstructorTest()
|
||||
{
|
||||
ExtensionDataDeserializeWithNonDefaultConstructor c = new ExtensionDataDeserializeWithNonDefaultConstructor("Name!");
|
||||
c._extensionData = new Dictionary<string, JToken>
|
||||
{
|
||||
{"Key!", "Value!"}
|
||||
};
|
||||
|
||||
string json = JsonConvert.SerializeObject(c, Formatting.Indented);
|
||||
|
||||
Assert.AreEqual(@"{
|
||||
""Name"": ""Name!"",
|
||||
""Key!"": ""Value!""
|
||||
}", json);
|
||||
|
||||
var c2 = JsonConvert.DeserializeObject<ExtensionDataDeserializeWithNonDefaultConstructor>(json);
|
||||
|
||||
Assert.AreEqual("Name!", c2.Name);
|
||||
Assert.IsNotNull(c2._extensionData);
|
||||
Assert.AreEqual(1, c2._extensionData.Count);
|
||||
Assert.AreEqual("Value!", (string)c2._extensionData["Key!"]);
|
||||
}
|
||||
|
||||
#if NETFX_CORE
|
||||
[Test]
|
||||
public void SerializeWinRTJsonObject()
|
||||
|
||||
@@ -178,7 +178,7 @@ namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
try
|
||||
{
|
||||
action();
|
||||
; action();
|
||||
|
||||
Assert.Fail("Exception of type {0} expected; got none exception", typeof(TException).Name);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (!ReflectionUtils.IsNullable(ReflectionUtils.GetMemberUnderlyingType(_memberInfo)))
|
||||
throw new JsonSerializationException("Incompatible value. Cannot set {0} to null.".FormatWith(CultureInfo.InvariantCulture, _memberInfo));
|
||||
}
|
||||
else if (!ReflectionUtils.GetMemberUnderlyingType(_memberInfo).IsAssignableFrom(value.GetType()))
|
||||
else if (!ReflectionUtils.GetMemberUnderlyingType(_memberInfo).IsInstanceOfType(value))
|
||||
{
|
||||
throw new JsonSerializationException("Incompatible value. Cannot set {0} to type {1}.".FormatWith(CultureInfo.InvariantCulture, _memberInfo, value.GetType()));
|
||||
}
|
||||
|
||||
@@ -1458,7 +1458,8 @@ To fix this error either change the environment to be fully trusted, change the
|
||||
if (TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Info)
|
||||
TraceWriter.Trace(TraceLevel.Info, JsonPosition.FormatMessage(reader as IJsonLineInfo, reader.Path, "Deserializing {0} using a non-default constructor '{1}'.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType, constructorInfo)), null);
|
||||
|
||||
IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndConstructorValues(contract, containerProperty, reader, objectType);
|
||||
IDictionary<string, object> extensionData;
|
||||
IDictionary<JsonProperty, object> propertyValues = ResolvePropertyAndConstructorValues(contract, containerProperty, reader, objectType, out extensionData);
|
||||
|
||||
IDictionary<ParameterInfo, object> constructorParameters = constructorInfo.GetParameters().ToDictionary(p => p, p => (object)null);
|
||||
IDictionary<JsonProperty, object> remainingPropertyValues = new Dictionary<JsonProperty, object>();
|
||||
@@ -1493,7 +1494,7 @@ To fix this error either change the environment to be fully trusted, change the
|
||||
JsonProperty property = remainingPropertyValue.Key;
|
||||
object value = remainingPropertyValue.Value;
|
||||
|
||||
if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
|
||||
if (ShouldSetPropertyValue(property, value))
|
||||
{
|
||||
property.ValueProvider.SetValue(createdObject, value);
|
||||
}
|
||||
@@ -1537,6 +1538,14 @@ To fix this error either change the environment to be fully trusted, change the
|
||||
}
|
||||
}
|
||||
|
||||
if (extensionData != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, object> e in extensionData)
|
||||
{
|
||||
contract.ExtensionDataSetter(createdObject, e.Key, e.Value);
|
||||
}
|
||||
}
|
||||
|
||||
EndObject(createdObject, reader, contract, reader.Depth, propertiesPresence);
|
||||
|
||||
OnDeserialized(reader, contract, createdObject);
|
||||
@@ -1556,8 +1565,10 @@ To fix this error either change the environment to be fully trusted, change the
|
||||
return value;
|
||||
}
|
||||
|
||||
private IDictionary<JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType)
|
||||
private IDictionary<JsonProperty, object> ResolvePropertyAndConstructorValues(JsonObjectContract contract, JsonProperty containerProperty, JsonReader reader, Type objectType, out IDictionary<string, object> extensionData)
|
||||
{
|
||||
extensionData = (contract.ExtensionDataSetter != null) ? new Dictionary<string, object>() : null;
|
||||
|
||||
IDictionary<JsonProperty, object> propertyValues = new Dictionary<JsonProperty, object>();
|
||||
bool exit = false;
|
||||
do
|
||||
@@ -1594,10 +1605,7 @@ To fix this error either change the environment to be fully trusted, change the
|
||||
propertyValue = CreateValueInternal(reader, property.PropertyType, property.PropertyContract, property, contract, containerProperty, null);
|
||||
|
||||
propertyValues[property] = propertyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Skip();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1610,7 +1618,15 @@ To fix this error either change the environment to be fully trusted, change the
|
||||
|
||||
if (Serializer._missingMemberHandling == MissingMemberHandling.Error)
|
||||
throw JsonSerializationException.Create(reader, "Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));
|
||||
}
|
||||
|
||||
if (extensionData != null)
|
||||
{
|
||||
object value = CreateValueInternal(reader, null, null, null, contract, containerProperty, null);
|
||||
extensionData[memberName] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Skip();
|
||||
}
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user