private object ReadJsonAsResourceObject(ForkableJsonReader reader, Type objectType, JsonSerializer serializer) { // if the value has been explicitly set to null then the value of the element is simply null if (reader.TokenType == JsonToken.Null) { return(null); } var serializationData = SerializationData.GetSerializationData(reader); var jsonApiContractResolver = (JsonApiContractResolver)serializer.ContractResolver; var reference = ReaderUtil.ReadAheadToIdentifyObject(reader); if (serializationData.Included.TryGetValue(reference, out object resourceObject)) { if (resourceObject is JObject resoruceObjectJObject) { // 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 now know what type it should be so will read it // as such var resourceObjectReader = new ForkableJsonReader(resoruceObjectJObject.CreateReader(), reader.SerializationDataToken); resourceObjectReader.Read(); //JObject readers begin at Not Started resourceObject = jsonApiContractResolver.ResourceObjectConverter.ReadJson( resourceObjectReader, objectType, null, serializer); } //push the reader to the end, we dont need anything else out of the reference ReaderUtil.ReadUntilEnd(reader, reader.Path); } else { var contract = (JsonObjectContract)jsonApiContractResolver.ResolveContract(objectType); resourceObject = ReaderUtil.CreateObject(serializationData, objectType, reference.Type, serializer); // for placeholders we will just read the top level properties // it is unlikely to have attributes/relationships present foreach (var propName in ReaderUtil.IterateProperties(reader)) { var successfullyPopulateProperty = ReaderUtil.TryPopulateProperty( serializer, resourceObject, contract.Properties.GetClosestMatchProperty(propName), reader); } serializationData.Included[reference] = resourceObject; } if (!TypeInfoShim.IsInstanceOf(objectType.GetTypeInfo(), resourceObject)) { throw new JsonSerializationException($"Unable to assign object '{resourceObject}' to type '{objectType}' at path {reader.FullPath}"); } return(resourceObject); }
internal bool IsExplicitRelationship(Type objectType) { var typeInfo = objectType.GetTypeInfo(); return(TypeInfoShim.GetPropertyFromInhertianceChain(typeInfo, PropertyNames.Data) != null || TypeInfoShim.GetPropertyFromInhertianceChain(typeInfo, PropertyNames.Links) != null); }
public override bool CanConvert(Type objectType) { var typeInfo = objectType.GetTypeInfo(); return(TypeInfoShim.GetPropertyFromInhertianceChain(typeInfo, PropertyNames.Data) != null || TypeInfoShim.GetPropertyFromInhertianceChain(typeInfo, PropertyNames.Links) != null); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var serializationData = SerializationData.GetSerializationData(reader); reader = new ForkableJsonReader(reader); var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(objectType); var rootObject = contract.DefaultCreator(); serializationData.HasProcessedDocumentRoot = true; var includedConverter = new IncludedConverter(); foreach (var propName in ReaderUtil.IterateProperties(reader)) { switch (propName) { case PropertyNames.Data: var documentRootInterfaceType = TypeInfoShim.GetInterfaces(objectType.GetTypeInfo()) .Select(x => x.GetTypeInfo()) .FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDocumentRoot <>)); var dataType = documentRootInterfaceType.GenericTypeArguments[0]; var dataObj = serializer.Deserialize(reader, dataType); contract.Properties.GetClosestMatchProperty(PropertyNames.Data).ValueProvider.SetValue(rootObject, dataObj); break; case PropertyNames.Included: //if our object has an included property we will do our best to populate it var property = contract.Properties.GetClosestMatchProperty(propName); if (ReaderUtil.CanPopulateProperty(property)) { ReaderUtil.TryPopulateProperty(serializer, rootObject, contract.Properties.GetClosestMatchProperty(propName), ((ForkableJsonReader)reader).Fork()); } //still need to read our values so they are updated foreach (var obj in ReaderUtil.IterateList(reader)) { var includedObject = includedConverter.ReadJson(reader, typeof(object), null, serializer); } break; default: ReaderUtil.TryPopulateProperty(serializer, rootObject, contract.Properties.GetClosestMatchProperty(propName), reader); break; } } return(rootObject); }
public override bool CanConvert(Type objectType) { var res = ((objectType.GetCustomAttributes(typeof(ResourceAttribute))).SingleOrDefault() as ResourceAttribute); if (res != null && !res.IsResource) { return(false); } return(TypeInfoShim.GetPropertyFromInhertianceChain(objectType.GetTypeInfo(), PropertyNames.Id) != null || TypeInfoShim.GetPropertyFromInhertianceChain(objectType.GetTypeInfo(), PropertyNames.Tid) != null); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { reader = new ForkableJsonReader(reader); var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(objectType); var rootObject = contract.DefaultCreator(); serializer.ReferenceResolver.AddReference(null, IncludedReferenceResolver.RootReference, rootObject); var includedConverter = new IncludedConverter(); foreach (var propName in ReaderUtil.IterateProperties(reader)) { switch (propName) { case PropertyNames.Data: var documentRootInterfaceType = TypeInfoShim.GetInterfaces(objectType.GetTypeInfo()) .Select(x => x.GetTypeInfo()) .FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDocumentRoot <>)); var dataType = documentRootInterfaceType.GenericTypeArguments[0]; var dataObj = serializer.Deserialize(reader, dataType); contract.Properties.GetClosestMatchProperty(PropertyNames.Data).ValueProvider.SetValue(rootObject, dataObj); break; case PropertyNames.Included: foreach (var obj in ReaderUtil.IterateList(reader)) { var includedObject = includedConverter.ReadJson(reader, typeof(object), null, serializer); } break; default: ReaderUtil.TryPopulateProperty(serializer, rootObject, contract.Properties.GetClosestMatchProperty(propName), reader); break; } } return(rootObject); }
public override bool CanConvert(Type objectType) { return(TypeInfoShim.GetPropertyFromInhertianceChain(objectType.GetTypeInfo(), "Id") != null); }
public override bool CanConvert(Type objectType) { return(TypeInfoShim.GetProperty(objectType.GetTypeInfo(), "Id") != null); }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(objectType); var rootObject = contract.DefaultCreator(); serializer.ReferenceResolver.AddReference(null, IncludedReferenceResolver.RootReference, rootObject); //var includedConverter = new IncludedConverter(); foreach (var propName in ReaderUtil.IterateProperties(reader)) { switch (propName) { case PropertyNames.Data: var documentRootInterfaceType = TypeInfoShim.GetInterfaces(objectType.GetTypeInfo()) .Select(x => x.GetTypeInfo()) .FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDocumentRoot <>)); var dataType = documentRootInterfaceType.GenericTypeArguments[0]; var dataObj = serializer.Deserialize(reader, dataType); contract.Properties.GetClosestMatchProperty(PropertyNames.Data).ValueProvider.SetValue(rootObject, dataObj); break; case PropertyNames.Included: // //if our object has an included property we will do our best to populate it // var property = contract.Properties.GetClosestMatchProperty(propName); // //if (ReaderUtil.CanPopulateProperty(property)) // //{ // // ReaderUtil.TryPopulateProperty(serializer, rootObject, contract.Properties.GetClosestMatchProperty(propName), ((ForkableJsonReader)reader).Fork()); // //} //still need to read our values so they are updated foreach (var obj in ReaderUtil.IterateList(reader)) { var type = ""; var id = ""; //read untill id and type foreach (var innerPropName in ReaderUtil.IterateProperties(reader)) { switch (innerPropName) { case PropertyNames.Type: type = reader.Value.ToString(); break; case PropertyNames.Id: id = reader.Value.ToString(); break; default: break; } if (!string.IsNullOrEmpty(type) && !string.IsNullOrEmpty(id)) { break; } } var existingObject = serializer.ReferenceResolver.ResolveReference(null, type + ":" + id); if (existingObject != null) { //We have an existing object, its likely our included data has more detail than what //is currently on the object so we will pass the reader so it can be deserialized again var inc_type = existingObject.GetType(); var existingObjectContract = serializer.ContractResolver.ResolveContract(inc_type); existingObjectContract.Converter.ReadJson(reader, inc_type, existingObject, serializer); } //contract.Converter.ReadJson(reader, typeof(object), rootObject, serializer); //var includedObject = includedConverter.ReadJson(reader, typeof(object), null, serializer); } break; default: ReaderUtil.TryPopulateProperty(serializer, rootObject, contract.Properties.GetClosestMatchProperty(propName), reader); break; } } return(rootObject); }
public static bool CanConvertStatic(Type objectType) { return(TypeInfoShim.GetInterfaces(objectType.GetTypeInfo()) .Select(x => x.GetTypeInfo()) .Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDocumentRoot <>))); }
internal bool IsExplicitResourceIdentifier(Type type) { return(TypeInfoShim.GetInterfaces(type.GetTypeInfo()) .Select(x => x.GetTypeInfo()) .Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IResourceIdentifier <>))); }
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; })); }