コード例 #1
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            object list;

            if (DocumentRootConverter.TryResolveAsRootData(reader, objectType, serializer, out list))
            {
                return(list);
            }

            //read into the 'Data' path
            var preDataPath = ReaderUtil.ReadUntilStart(reader, DataPathRegex);

            //we should be dealing with list types, but we also want the element type
            Type elementType;

            if (!ListUtil.IsList(objectType, out elementType))
            {
                throw new ArgumentException($"{typeof(ResourceObjectListConverter)} can only read json lists", nameof(objectType));
            }

            var itemsIterator = ReaderUtil.IterateList(reader).Select(x => serializer.Deserialize(reader, elementType));

            list = ListUtil.CreateList(objectType, itemsIterator);

            //read out of the 'Data' path
            ReaderUtil.ReadUntilEnd(reader, preDataPath);

            return(list);
        }
コード例 #2
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);
        }
コード例 #3
0
        protected object PopulateProperties(JsonSerializer serializer, object obj, JsonReader reader, JsonObjectContract contract)
        {
            foreach (var propName in ReaderUtil.IterateProperties(reader))
            {
                if (propName == PropertyNames.Type)
                {
                    var type = reader.Value;
                    if (obj.GetType().Name.ToLower() != type.ToString().ToLower())
                    {
                        Assembly[] assembly = Utility.GetAssemblies();
                        var        tp       = assembly.SelectMany(s => s.GetTypes()).ToList().Where(t => t.Name.ToLower() == type.ToString().ToLower()).SingleOrDefault();
                        if (tp != null)
                        {
                            obj      = Activator.CreateInstance(tp);
                            contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(obj.GetType());
                        }
                    }
                    //retObj.id = obj;
                }
                var successfullyPopulateProperty = ReaderUtil.TryPopulateProperty(
                    serializer,
                    obj,
                    contract.Properties.GetClosestMatchProperty(propName),
                    reader);

                if (!successfullyPopulateProperty)
                {
                    //flatten out attributes onto the object
                    if (propName == "attributes")
                    {
                        foreach (var innerPropName in ReaderUtil.IterateProperties(reader))
                        {
                            ReaderUtil.TryPopulateProperty(
                                serializer,
                                obj,
                                contract.Properties.GetClosestMatchProperty(innerPropName),
                                reader);
                        }
                    }

                    //flatten out relationships onto the object
                    if (propName == "relationships")
                    {
                        foreach (var innerPropName in ReaderUtil.IterateProperties(reader))
                        {
                            //read into the 'Data' path
                            var preDataPath = ReaderUtil.ReadUntilStart(reader, DataPathRegex);

                            ReaderUtil.TryPopulateProperty(
                                serializer,
                                obj,
                                contract.Properties.GetClosestMatchProperty(innerPropName),
                                reader);
                            //read out of the 'Data' path
                            ReaderUtil.ReadUntilEnd(reader, preDataPath);
                        }
                    }
                }
            }
            return(obj);
        }