internal static bool TryResolveAsRootError(JsonReader reader, Type objectType, JsonSerializer serializer, out IEnumerable <IError> obj)
        {
            var serializationData = SerializationData.GetSerializationData(reader);

            //if we already have a root object then we dont need to resolve the root object
            if (serializationData.HasProcessedDocumentRoot)
            {
                obj = null;
                return(false);
            }

            //determine the error class type. The type passed in could be an array or an object
            //so we need to determine the error type for both
            Type errorElementType;

            if (!ListUtil.IsList(objectType, out errorElementType))
            {
                errorElementType = objectType;
            }

            //we do not have a root object, so this is probably the entry point, so we will resolve
            //a document root and return the data object
            var documentRootType = typeof(MinimalDocumentRoot <,>).MakeGenericType(typeof(object), errorElementType);
            var objContract      = (JsonObjectContract)serializer.ContractResolver.ResolveContract(documentRootType);
            var dataProp         = objContract.Properties.GetClosestMatchProperty("errors");

            var root = serializer.Deserialize(reader, documentRootType);

            obj = (IEnumerable <IError>)dataProp.ValueProvider.GetValue(root);
            return(true);
        }
        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);
        }
Пример #3
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))));
        }
Пример #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
            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))));
        }
Пример #5
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);
        }
Пример #6
0
        internal static IEnumerable <IError> ResolveAsRootError(JsonReader reader, Type objectType, JsonSerializer serializer)
        {
            //determine the error class type. The type passed in could be an array or an object
            //so we need to determine the error type for both
            Type errorElementType;

            if (!ListUtil.IsList(objectType, out errorElementType))
            {
                errorElementType = objectType;
            }

            //we do not have a root object, so this is probably the entry point, so we will resolve
            //a document root and return the data object
            var documentRootType = typeof(MinimalDocumentRoot <,>).MakeGenericType(typeof(object), errorElementType);
            var objContract      = (JsonObjectContract)serializer.ContractResolver.ResolveContract(documentRootType);
            var dataProp         = objContract.Properties.GetClosestMatchProperty("errors");

            var root = serializer.Deserialize(reader, documentRootType);

            return((IEnumerable <IError>)dataProp.ValueProvider.GetValue(root));
        }
Пример #7
0
        public static bool CanConvertStatic(Type objectType)
        {
            Type elementType;

            return(ListUtil.IsList(objectType, out elementType) && ErrorConverter.CanConvertStatic(elementType));
        }
        private void WriteResourceJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var resolver     = (serializer.ReferenceResolver as IncludedReferenceResolver);
            var currentIndex = resolver.RefList.Count;
            var valueType    = value.GetType();

            //Serialize object
            var contract = (JsonObjectContract)serializer.ContractResolver.ResolveContract(valueType);

            writer.WriteStartObject();

            //will capture id and type as we go through
            object id   = null;
            object type = null;

            //Handle link
            var linkProps = valueType.GetProperties().Where(p => p.GetCustomAttributes(typeof(ResourceAttribute), false).Count() != 0).ToList();

            //A resource object MUST contain at least the following top-level members: type
            var typeProp = contract.Properties.GetClosestMatchProperty("type");

            type = GenerateDefaultTypeName(valueType);
            if (typeProp == null)
            {
                writer.WritePropertyName("type");
                serializer.Serialize(writer, type);
            }

            List <JsonWriterCapture> attributes    = new List <JsonWriterCapture>();
            List <JsonWriterCapture> relationships = new List <JsonWriterCapture>();

            foreach (var prop in contract.Properties.Where(x => !x.Ignored))
            {
                var propValue = prop.ValueProvider.GetValue(value);
                if (propValue == null && (prop.NullValueHandling ?? serializer.NullValueHandling) == NullValueHandling.Ignore)
                {
                    continue;
                }

                switch (prop.PropertyName)
                {
                //In addition, a resource object MAY contain any of these top - level members: links, meta, attributes, relationships
                case PropertyNames.Id:     //Id is optional on base objects
                case PropertyNames.Tid:    //
                    id = propValue;
                    writer.WritePropertyName(prop.PropertyName);
                    serializer.Serialize(writer, id);
                    break;

                case PropertyNames.Meta:
                    writer.WritePropertyName(prop.PropertyName);
                    serializer.Serialize(writer, propValue);
                    break;

                case PropertyNames.Type:
                    writer.WritePropertyName(PropertyNames.Type);
                    type = typeProp?.ValueProvider?.GetValue(value) ?? GenerateDefaultTypeName(valueType);
                    serializer.Serialize(writer, type);
                    break;

                default:
                    var resAttr = linkProps?.Where(l => l.Name.ToLower() == prop.PropertyName.ToLower()).SingleOrDefault();

                    //we do not know if it is an Attribute or a Relationship
                    //so we will send out a probe to determine which one it is
                    var probe = new AttributeOrRelationshipProbe();
                    probe.WritePropertyName(prop.PropertyName);
                    serializer.Serialize(probe, propValue);

                    //handle relationship links start
                    if (probe.PropertyType == AttributeOrRelationshipProbe.Type.Relationship)
                    {
                        ResourceAttribute link = null;
                        if (resAttr != null)
                        {
                            link = resAttr.GetCustomAttributes(typeof(ResourceAttribute), false)[0] as ResourceAttribute;
                            if (link.Links != null && link.Links.Count > 0)
                            {
                                //probe.WriteStartObject();
                                var act = probe.GetActions();
                                //001:remove last entry and add links
                                act.RemoveAt(act.Count - 1);

                                WriterUtil.GenerateResourceLinks(serializer, probe, value, link, type.ToString(), prop.PropertyName, propValue);
                                //additional end object since it is removed to add links in 001 section
                                probe.AddEndObject();
                            }
                            if (!link.IsResource)
                            {
                                probe.PropertyType = AttributeOrRelationshipProbe.Type.Attribute;
                            }
                        }

                        //Handle Includes
                        if (resolver.Includes != null && resolver.Includes.Count() > 0)
                        {
                            if (ListUtil.IsList(propValue.GetType()))
                            {
                                var enumerable   = propValue as IEnumerable <object> ?? Enumerable.Empty <object>();
                                var include_name = ((link != null && !string.IsNullOrEmpty(link.IncludeName)) ? link.IncludeName : prop.PropertyName);
                                if (enumerable.Count() > 0 && resolver.Includes.Contains(include_name.ToLower()))
                                {
                                    foreach (var valueElement in enumerable)
                                    {
                                        var include_id   = valueElement.GetType().GetProperties().Where(p => p.Name.ToLower() == PropertyNames.Id).FirstOrDefault()?.GetValue(valueElement);
                                        var include_type = valueElement.GetType().GetProperties().Where(p => p.Name.ToLower() == PropertyNames.Type).FirstOrDefault()?.GetValue(valueElement);
                                        if (include_type == null)
                                        {
                                            include_type = valueElement.GetType().Name.ToLower();
                                        }
                                        if (include_id != null && include_type != null)
                                        {
                                            var refer = IncludedReferenceResolver.GetReferenceValue(include_id.ToString(), include_type.ToString());
                                            resolver.ResourceToInclude.Add(refer);
                                            serializer.ReferenceResolver.AddReference(null, refer, valueElement);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                var include_id   = propValue.GetType().GetProperties().Where(p => p.Name.ToLower() == PropertyNames.Id).FirstOrDefault()?.GetValue(propValue);
                                var include_type = propValue.GetType().GetProperties().Where(p => p.Name.ToLower() == PropertyNames.Type).FirstOrDefault()?.GetValue(propValue);
                                if (include_type == null)
                                {
                                    include_type = propValue.GetType().Name.ToLower();
                                }
                                if (include_id != null && include_type != null)
                                {
                                    var include_name = ((link != null && !string.IsNullOrEmpty(link.IncludeName)) ? link.IncludeName : prop.PropertyName);
                                    if (resolver.Includes != null && resolver.Includes.Contains(include_name.ToLower()))
                                    {
                                        var refer = IncludedReferenceResolver.GetReferenceValue(include_id.ToString(), include_type.ToString());
                                        resolver.ResourceToInclude.Add(refer);
                                        serializer.ReferenceResolver.AddReference(null, refer, propValue);
                                    }
                                }
                            }
                        }
                    }
                    //handle relationship links end

                    (probe.PropertyType == AttributeOrRelationshipProbe.Type.Attribute
                                   ? attributes
                                   : relationships).Add(probe);

                    break;
                }
            }

            //add reference to this type, so others can reference it
            var referenceValue = IncludedReferenceResolver.GetReferenceValue(id?.ToString(), type?.ToString());

            serializer.ReferenceResolver.AddReference(null, referenceValue, value);
            resolver?.RenderedReferences?.Add(referenceValue);

            //set parent reference for generating link parameters
            for (int i = currentIndex; i < resolver.RefList.Count; i++)
            {
                if (resolver.RefList[i].Reference != referenceValue)
                {
                    resolver.RefList[i].ParentReference = referenceValue;
                }
            }
            //output our attibutes in an attribute tag
            if (attributes.Count > 0)
            {
                writer.WritePropertyName(PropertyNames.Attributes);
                writer.WriteStartObject();
                foreach (var attribute in attributes)
                {
                    attribute.ApplyCaptured(writer);
                }
                writer.WriteEndObject();
            }

            //output our relationships in a relationship tag
            if (relationships.Count > 0)
            {
                writer.WritePropertyName(PropertyNames.Relationships);
                writer.WriteStartObject();

                foreach (var relationship in relationships)
                {
                    relationship.ApplyCaptured(writer);
                }
                writer.WriteEndObject();
            }
            //Links
            var res = ((value.GetType().GetCustomAttributes(typeof(ResourceAttribute))).SingleOrDefault() as ResourceAttribute);

            WriterUtil.GenerateResourceLinks(serializer, writer, value, res, type.ToString());

            writer.WriteEndObject();
        }
Пример #9
0
 public static bool CanConvertStatic(Type objectType, JsonConverter elementConvertor)
 {
     return(ListUtil.IsList(objectType, out Type elementType) &&
            elementConvertor.CanConvert(elementType));
 }
        public override bool CanConvert(Type objectType)
        {
            Type elementType;

            return(ListUtil.IsList(objectType, out elementType) && ResourceObjectConverter.CanConvert(elementType));
        }
Пример #11
0
 private bool IsArrayOf(Type type, Func <Type, bool> elementTypeCheck)
 {
     return(ListUtil.IsList(type, out Type elementType) &&
            elementTypeCheck(elementType));
 }