public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { //we may be starting the deserialization here, if thats the case we need to resolve this object as the root object obj; if (DocumentRootConverter.TryResolveAsRootData(reader, objectType, serializer, out obj)) { return(obj); } //read into the 'Data' element return(ReaderUtil.ReadInto( reader as ForkableJsonReader ?? new ForkableJsonReader(reader), DataReadPathRegex, dataReader => { //if the value has been explicitly set to null then the value of the element is simply null if (dataReader.TokenType == JsonToken.Null) { return null; } JsonObjectContract contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(objectType); var serializationData = SerializationData.GetSerializationData(dataReader); //if we arent given an existing value check the references to see if we have one in there //if we dont have one there then create a new object to populate if (existingValue == null) { var reference = ReaderUtil.ReadAheadToIdentifyObject(dataReader); if (!serializationData.Included.TryGetValue(reference, out existingValue)) { existingValue = contract.DefaultCreator(); serializationData.Included.Add(reference, existingValue); } if (existingValue is JObject) { //sometimes the value in the reference resolver is a JObject. This occurs when we //did not know what type it should be when we first read it (i.e. included was processed //before the item). In these cases we will create a new object and read data from the JObject dataReader = new ForkableJsonReader(((JObject)existingValue).CreateReader(), dataReader.SerializationDataToken); dataReader.Read(); //JObject readers begin at Not Started existingValue = contract.DefaultCreator(); serializationData.Included[reference] = existingValue; } } PopulateProperties(serializer, existingValue, dataReader, contract); return existingValue; })); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { //we may be starting the deserialization here, if thats the case we need to resolve this object as the root if (DocumentRootConverter.TryResolveAsRootData(reader, objectType, serializer, out object obj)) { return(obj); } //read into the 'Data' element return(ReaderUtil.ReadInto( reader as ForkableJsonReader ?? new ForkableJsonReader(reader), DataReadPathRegex, dataReader => { //if they have custom convertors registered, we will respect them var customConvertor = serializer.Converters.FirstOrDefault(x => x.CanRead && x.CanConvert(objectType)); if (customConvertor != null && customConvertor != this) { return customConvertor.ReadJson(reader, objectType, existingValue, serializer); } //if the value has been explicitly set to null then the value of the element is simply null if (dataReader.TokenType == JsonToken.Null) { return null; } var serializationData = SerializationData.GetSerializationData(dataReader); //if we arent given an existing value check the references to see if we have one in there //if we dont have one there then create a new object to populate if (existingValue == null) { var reference = ReaderUtil.ReadAheadToIdentifyObject(dataReader); if (!serializationData.Included.TryGetValue(reference, out existingValue)) { existingValue = CreateObject(objectType, reference.Type, serializer); serializationData.Included.Add(reference, existingValue); } if (existingValue is JObject existingValueJObject) { //sometimes the value in the reference resolver is a JObject. This occurs when we //did not know what type it should be when we first read it (i.e. included was processed //before the item). In these cases we will create a new object and read data from the JObject dataReader = new ForkableJsonReader(existingValueJObject.CreateReader(), dataReader.SerializationDataToken); dataReader.Read(); //JObject readers begin at Not Started existingValue = CreateObject(objectType, reference.Type, serializer); serializationData.Included[reference] = existingValue; } } //additional check to ensure the object we created is of the correct type if (!TypeInfoShim.IsInstanceOf(objectType.GetTypeInfo(), existingValue)) { throw new JsonSerializationException($"Unable to assign object '{existingValue}' to type '{objectType}'"); } PopulateProperties(serializer, existingValue, dataReader); return existingValue; })); }