-Fixed type name handling when a property already has a base type assigned
This commit is contained in:
@@ -1740,6 +1740,34 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !NET20
|
||||
[Test]
|
||||
public void ExistingBaseValue()
|
||||
{
|
||||
string json = @"{
|
||||
""itemIdentifier"": {
|
||||
""$type"": ""Newtonsoft.Json.Tests.Serialization.ReportItemKeys, Newtonsoft.Json.Tests"",
|
||||
""dataType"": 0,
|
||||
""wantedUnitID"": 1,
|
||||
""application"": 3,
|
||||
""id"": 101,
|
||||
""name"": ""Machine""
|
||||
},
|
||||
""isBusinessEntity"": false,
|
||||
""isKeyItem"": true,
|
||||
""summarizeOnThisItem"": false
|
||||
}";
|
||||
|
||||
GroupingInfo g = JsonConvert.DeserializeObject<GroupingInfo>(json, new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = TypeNameHandling.Objects
|
||||
});
|
||||
|
||||
ReportItemKeys item = (ReportItemKeys)g.ItemIdentifier;
|
||||
Assert.AreEqual(1, item.WantedUnitID);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !NETFX_CORE
|
||||
@@ -1941,6 +1969,42 @@ namespace Newtonsoft.Json.Tests.Serialization
|
||||
public string String { get; set; }
|
||||
public int Integer { get; set; }
|
||||
}
|
||||
|
||||
#if !NET20
|
||||
[DataContract]
|
||||
public class GroupingInfo
|
||||
{
|
||||
[DataMember]
|
||||
public ApplicationItemKeys ItemIdentifier { get; set; }
|
||||
|
||||
public GroupingInfo()
|
||||
{
|
||||
ItemIdentifier = new ApplicationItemKeys();
|
||||
}
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
public class ApplicationItemKeys
|
||||
{
|
||||
[DataMember]
|
||||
public int ID { get; set; }
|
||||
[DataMember]
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
[DataContract]
|
||||
public class ReportItemKeys : ApplicationItemKeys
|
||||
{
|
||||
protected ulong _wantedUnit;
|
||||
|
||||
[DataMember]
|
||||
public ulong WantedUnitID
|
||||
{
|
||||
get { return _wantedUnit; }
|
||||
set { _wantedUnit = value; }
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -374,6 +374,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
{
|
||||
string id;
|
||||
object newValue;
|
||||
Type resolvedObjectType = objectType;
|
||||
|
||||
if (Serializer.SpecialPropertyHandling == SpecialPropertyHandling.ReadAhead)
|
||||
{
|
||||
@@ -389,13 +390,13 @@ namespace Newtonsoft.Json.Serialization
|
||||
reader = tokenReader;
|
||||
}
|
||||
|
||||
if (ReadSpecialPropertiesToken(tokenReader, ref objectType, ref contract, member, containerContract, containerMember, existingValue, out newValue, out id))
|
||||
if (ReadSpecialPropertiesToken(tokenReader, ref resolvedObjectType, ref contract, member, containerContract, containerMember, existingValue, out newValue, out id))
|
||||
return newValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckedRead(reader);
|
||||
if (ReadSpecialProperties(reader, ref objectType, ref contract, member, containerContract, containerMember, existingValue, out newValue, out id))
|
||||
if (ReadSpecialProperties(reader, ref resolvedObjectType, ref contract, member, containerContract, containerMember, existingValue, out newValue, out id))
|
||||
return newValue;
|
||||
}
|
||||
|
||||
@@ -409,7 +410,8 @@ namespace Newtonsoft.Json.Serialization
|
||||
bool createdFromNonDefaultConstructor = false;
|
||||
JsonObjectContract objectContract = (JsonObjectContract)contract;
|
||||
object targetObject;
|
||||
if (existingValue != null)
|
||||
// check that if type name handling is being used that the existing value is compatible with the specified type
|
||||
if (existingValue != null && (resolvedObjectType == objectType || resolvedObjectType.IsInstanceOfType(existingValue)))
|
||||
targetObject = existingValue;
|
||||
else
|
||||
targetObject = CreateNewObject(reader, objectContract, member, containerMember, id, out createdFromNonDefaultConstructor);
|
||||
@@ -433,7 +435,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
if (reader.TokenType == JsonToken.StartObject)
|
||||
throw JsonSerializationException.Create(reader, "Unexpected token when deserializing primitive value: " + reader.TokenType);
|
||||
|
||||
object value = CreateValueInternal(reader, objectType, primitiveContract, member, null, null, existingValue);
|
||||
object value = CreateValueInternal(reader, resolvedObjectType, primitiveContract, member, null, null, existingValue);
|
||||
|
||||
CheckedRead(reader);
|
||||
return value;
|
||||
@@ -503,7 +505,7 @@ namespace Newtonsoft.Json.Serialization
|
||||
|
||||
throw JsonSerializationException.Create(reader, @"Cannot deserialize the current JSON object (e.g. {{""name"":""value""}}) into type '{0}' because the type requires a {1} to deserialize correctly.
|
||||
To fix this error either change the JSON to a {1} or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
|
||||
".FormatWith(CultureInfo.InvariantCulture, objectType, GetExpectedDescription(contract)));
|
||||
".FormatWith(CultureInfo.InvariantCulture, resolvedObjectType, GetExpectedDescription(contract)));
|
||||
}
|
||||
|
||||
private bool ReadSpecialPropertiesToken(JTokenReader reader, ref Type objectType, ref JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue, out object newValue, out string id)
|
||||
|
||||
Reference in New Issue
Block a user