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);
        }
Example #2
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var serializationData       = SerializationData.GetSerializationData(reader);
            var forkableReader          = reader as ForkableJsonReader ?? new ForkableJsonReader(reader);
            var jsonApiContractResolver = (JsonApiContractResolver)serializer.ContractResolver;
            var contract = jsonApiContractResolver.ResolveContract(objectType);

            switch (contract)
            {
            case ResourceObjectContract roc:
                return(ReadJsonAsResourceObject(forkableReader, objectType, serializer));

            case ResourceIdentifierContract ric:
                return(ReadJsonAsExplicitResourceIdentifier(forkableReader, objectType, serializer));

            case JsonArrayContract jac when forkableReader.TokenType == JsonToken.StartArray:
                var list = new List <object>();
                foreach (var item in ReaderUtil.IterateList(forkableReader))
                {
                    list.Add(ReadJson(forkableReader, jac.CollectionItemType, null, serializer));
                }
                return(ListUtil.CreateList(objectType, list));

            default:
                return(serializer.Deserialize(reader, objectType));

                throw new JsonApiFormatException(
                          forkableReader.FullPath,
                          $"Expected to find a resource identifier or resource object, but found '{objectType}'",
                          "Resource indentifier objects MUST contain 'id' members");
            }
        }
        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);
        }
Example #4
0
        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
            IEnumerable <IError> errors;

            if (DocumentRootConverter.TryResolveAsRootError(reader, objectType, serializer, out errors))
            {
                return(ListUtil.CreateList(objectType, errors));
            }

            Type elementType;

            ListUtil.IsList(objectType, out elementType);

            return(ListUtil.CreateList(objectType,
                                       ReaderUtil.IterateList(reader)
                                       .Select(x => serializer.Deserialize(reader, elementType))));
        }
        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
            var serializationData = SerializationData.GetSerializationData(reader);

            if (!serializationData.HasProcessedDocumentRoot)
            {
                var errors = DocumentRootConverter.ResolveAsRootError(reader, objectType, serializer);
                return(ListUtil.CreateList(objectType, errors));
            }

            Type elementType;

            ListUtil.IsList(objectType, out elementType);

            return(ListUtil.CreateList(objectType,
                                       ReaderUtil.IterateList(reader)
                                       .Select(x => serializer.Deserialize(reader, elementType))));
        }
        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);
        }
Example #7
0
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var serializationData = SerializationData.GetSerializationData(reader);

            if (!serializationData.HasProcessedDocumentRoot)
            {
                return(DocumentRootConverter.ResolveAsRootData(reader, objectType, serializer));
            }

            //we should be dealing with list types, but we also want the element type
            if (!ListUtil.IsList(objectType, out Type elementType))
            {
                throw new ArgumentException($"{typeof(ResourceObjectListConverter)} can only read json lists", nameof(objectType));
            }

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

            return(list);
        }
        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);
        }