Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        internal bool IsExplicitRelationship(Type objectType)
        {
            var typeInfo = objectType.GetTypeInfo();

            return(TypeInfoShim.GetPropertyFromInhertianceChain(typeInfo, PropertyNames.Data) != null ||
                   TypeInfoShim.GetPropertyFromInhertianceChain(typeInfo, PropertyNames.Links) != null);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 7
0
 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 <>)));
 }
Ejemplo n.º 11
0
 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;
            }));
        }