private static object ConvertCollectionValue(ODataCollectionValue collection,
                                                     ref IEdmTypeReference propertyType, ODataDeserializerProvider deserializerProvider,
                                                     ODataDeserializerContext readContext)
        {
            IEdmCollectionTypeReference collectionType;

            if (propertyType == null)
            {
                // dynamic collection property
                Contract.Assert(!String.IsNullOrEmpty(collection.TypeName),
                                "ODataLib should have verified that dynamic collection value has a type name " +
                                "since we provided metadata.");

                string         elementTypeName = GetCollectionElementTypeName(collection.TypeName, isNested: false);
                IEdmModel      model           = readContext.Model;
                IEdmSchemaType elementType     = model.FindType(elementTypeName);
                Contract.Assert(elementType != null);
                collectionType =
                    new EdmCollectionTypeReference(
                        new EdmCollectionType(elementType.ToEdmTypeReference(isNullable: false)));
                propertyType = collectionType;
            }
            else
            {
                collectionType = propertyType as IEdmCollectionTypeReference;
                Contract.Assert(collectionType != null, "The type for collection must be a IEdmCollectionType.");
            }

            ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(collectionType);

            return(deserializer.ReadInline(collection, collectionType, readContext));
        }
        /// <summary>
        /// Deserializes the given <paramref name="entryWrapper"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="entryWrapper">The OData entry to deserialize.</param>
        /// <param name="entityType">The entity type of the entry to deserialize.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <returns>The deserialized entity.</returns>
        public virtual object ReadEntry(ODataEntryWithNavigationLinks entryWrapper, IEdmEntityTypeReference entityType,
                                        ODataDeserializerContext readContext)
        {
            if (entryWrapper == null)
            {
                throw Error.ArgumentNull("entryWrapper");
            }

            if (readContext == null)
            {
                throw Error.ArgumentNull("readContext");
            }

            if (!String.IsNullOrEmpty(entryWrapper.Entry.TypeName) && entityType.FullName() != entryWrapper.Entry.TypeName)
            {
                // received a derived type in a base type deserializer. delegate it to the appropriate derived type deserializer.
                IEdmModel model = readContext.Model;

                if (model == null)
                {
                    throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext);
                }

                IEdmEntityType actualType = model.FindType(entryWrapper.Entry.TypeName) as IEdmEntityType;
                if (actualType == null)
                {
                    throw new ODataException(Error.Format(SRResources.EntityTypeNotInModel, entryWrapper.Entry.TypeName));
                }

                if (actualType.IsAbstract)
                {
                    string message = Error.Format(SRResources.CannotInstantiateAbstractEntityType, entryWrapper.Entry.TypeName);
                    throw new ODataException(message);
                }

                IEdmTypeReference        actualEntityType = new EdmEntityTypeReference(actualType, isNullable: false);
                ODataEdmTypeDeserializer deserializer     = DeserializerProvider.GetEdmTypeDeserializer(actualEntityType);
                if (deserializer == null)
                {
                    throw new SerializationException(
                              Error.Format(SRResources.TypeCannotBeDeserialized, actualEntityType.FullName(), typeof(ODataMediaTypeFormatter).Name));
                }

                object resource = deserializer.ReadInline(entryWrapper, actualEntityType, readContext);

                EdmStructuredObject structuredObject = resource as EdmStructuredObject;
                if (structuredObject != null)
                {
                    structuredObject.ExpectedEdmType = entityType.EntityDefinition();
                }

                return(resource);
            }
            else
            {
                object resource = CreateEntityResource(entityType, readContext);
                ApplyEntityProperties(resource, entryWrapper, entityType, readContext);
                return(resource);
            }
        }
        private static object ConvertComplexValue(ODataComplexValue complexValue, ref IEdmTypeReference propertyType,
                                                  ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext)
        {
            IEdmComplexTypeReference edmComplexType;

            if (propertyType == null)
            {
                // open complex property
                Contract.Assert(!String.IsNullOrEmpty(complexValue.TypeName),
                                "ODataLib should have verified that open complex value has a type name since we provided metadata.");
                IEdmModel model   = readContext.Model;
                IEdmType  edmType = model.FindType(complexValue.TypeName);
                Contract.Assert(edmType.TypeKind == EdmTypeKind.Complex, "ODataLib should have verified that complex value has a complex resource type.");
                edmComplexType = new EdmComplexTypeReference(edmType as IEdmComplexType, isNullable: true);
                propertyType   = edmComplexType;
            }
            else
            {
                edmComplexType = propertyType.AsComplex();
            }

            ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(edmComplexType);

            return(deserializer.ReadInline(complexValue, propertyType, readContext));
        }
        /// <summary>
        /// Deserializes the given <paramref name="collectionValue"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="collectionValue">The <see cref="ODataCollectionValue"/> to deserialize.</param>
        /// <param name="elementType">The element type of the collection to read.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <returns>The deserialized collection.</returns>
        public virtual IEnumerable ReadCollectionValue(ODataCollectionValue collectionValue, IEdmTypeReference elementType,
                                                       ODataDeserializerContext readContext)
        {
            if (collectionValue == null)
            {
                throw Error.ArgumentNull("collectionValue");
            }
            if (elementType == null)
            {
                throw Error.ArgumentNull("elementType");
            }

            ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(elementType);

            if (deserializer == null)
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeDeserialized, elementType.FullName(), typeof(ODataMediaTypeFormatter).Name));
            }

            foreach (object entry in collectionValue.Items)
            {
                if (elementType.IsPrimitive())
                {
                    yield return(entry);
                }
                else
                {
                    yield return(deserializer.ReadInline(entry, elementType, readContext));
                }
            }
        }
Exemple #5
0
        private static object ConvertCollectionValue(ODataCollectionValue collection, IEdmTypeReference propertyType,
                                                     ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext)
        {
            IEdmCollectionTypeReference collectionType = propertyType as IEdmCollectionTypeReference;

            Contract.Assert(collectionType != null, "The type for collection must be a IEdmCollectionType.");

            ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(collectionType);

            return(deserializer.ReadInline(collection, collectionType, readContext));
        }
Exemple #6
0
        private object ReadNestedResourceInline(ODataResourceWrapper resourceWrapper, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            Contract.Assert(edmType != null);
            Contract.Assert(readContext != null);

            if (resourceWrapper == null)
            {
                return(null);
            }

            ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(edmType);

            if (deserializer == null)
            {
                throw new SerializationException(Error.Format(SRResources.TypeCannotBeDeserialized,
                                                              edmType.FullName(), typeof(ODataMediaTypeFormatter)));
            }

            IEdmStructuredTypeReference structuredType = edmType.AsStructured();

            var nestedReadContext = new ODataDeserializerContext
            {
                Path  = readContext.Path,
                Model = readContext.Model,
            };

            if (readContext.IsUntyped)
            {
                if (structuredType.IsEntity())
                {
                    nestedReadContext.ResourceType = typeof(EdmEntityObject);
                }
                else
                {
                    nestedReadContext.ResourceType = typeof(EdmComplexObject);
                }
            }
            else
            {
                Type clrType = EdmLibHelpers.GetClrType(structuredType, readContext.Model);

                if (clrType == null)
                {
                    throw new ODataException(
                              Error.Format(SRResources.MappingDoesNotContainResourceType, structuredType.FullName()));
                }

                nestedReadContext.ResourceType = clrType;
            }

            return(deserializer.ReadInline(resourceWrapper, edmType, nestedReadContext));
        }
        /// <summary>
        /// Deserializes the given <paramref name="feed"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="feed">The feed to deserialize.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <param name="elementType">The element type of the feed being read.</param>
        /// <returns>The deserialized feed object.</returns>
        public virtual IEnumerable ReadFeed(ODataFeedWithEntries feed, IEdmEntityTypeReference elementType, ODataDeserializerContext readContext)
        {
            ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(elementType);

            if (deserializer == null)
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeDeserialized, elementType.FullName(), typeof(ODataMediaTypeFormatter).Name));
            }

            foreach (ODataEntryWithNavigationLinks entry in feed.Entries)
            {
                yield return(deserializer.ReadInline(entry, elementType, readContext));
            }
        }
        /// <summary>
        /// Deserializes the given <paramref name="resourceSet"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="resourceSet">The resource set to deserialize.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <param name="elementType">The element type of the resource set being read.</param>
        /// <returns>The deserialized resource set object.</returns>
        public virtual IEnumerable ReadResourceSet(ODataResourceSetWrapper resourceSet, IEdmStructuredTypeReference elementType, ODataDeserializerContext readContext)
        {
            ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(elementType);

            if (deserializer == null)
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeDeserialized, elementType.FullName(), typeof(ODataMediaTypeFormatter).Name));
            }

            foreach (ODataResourceWrapper resourceWrapper in resourceSet.Resources)
            {
                yield return(deserializer.ReadInline(resourceWrapper, elementType, readContext));
            }
        }
        private void ApplyFeedInNavigationProperty(IEdmNavigationProperty navigationProperty, object entityResource, ODataFeedWithEntries feed, ODataDeserializerContext readContext)
        {
            Contract.Assert(navigationProperty != null && navigationProperty.PropertyKind == EdmPropertyKind.Navigation, "navigationProperty != null && navigationProperty.TypeKind == ResourceTypeKind.EntityType");
            Contract.Assert(entityResource != null, "entityResource != null");

            if (readContext.IsDeltaOfT)
            {
                string message = Error.Format(SRResources.CannotPatchNavigationProperties, navigationProperty.Name, navigationProperty.DeclaringEntityType().FullName());
                throw new ODataException(message);
            }

            ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(navigationProperty.Type);

            if (deserializer == null)
            {
                throw new SerializationException(Error.Format(SRResources.TypeCannotBeDeserialized, navigationProperty.Type.FullName(), typeof(ODataMediaTypeFormatter)));
            }
            object value = deserializer.ReadInline(feed, navigationProperty.Type, readContext);

            string propertyName = EdmLibHelpers.GetClrPropertyName(navigationProperty, readContext.Model);

            DeserializationHelpers.SetCollectionProperty(entityResource, navigationProperty, value, propertyName, readContext.TimeZoneInfo);
        }
Exemple #10
0
        /// <summary>
        /// Deserializes the given <paramref name="complexValue"/> under the given <paramref name="readContext"/>.
        /// </summary>
        /// <param name="complexValue">The complex value to deserialize.</param>
        /// <param name="complexType">The EDM type of the complex value to read.</param>
        /// <param name="readContext">The deserializer context.</param>
        /// <returns>The deserialized complex value.</returns>
        public virtual object ReadComplexValue(ODataComplexValue complexValue, IEdmComplexTypeReference complexType,
                                               ODataDeserializerContext readContext)
        {
            if (complexValue == null)
            {
                throw Error.ArgumentNull("complexValue");
            }

            if (readContext == null)
            {
                throw Error.ArgumentNull("readContext");
            }

            if (readContext.Model == null)
            {
                throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext);
            }

            if (!String.IsNullOrEmpty(complexValue.TypeName) && complexType.FullName() != complexValue.TypeName)
            {
                // received a derived complex type in a base type deserializer.
                IEdmModel model = readContext.Model;
                if (model == null)
                {
                    throw Error.Argument("readContext", SRResources.ModelMissingFromReadContext);
                }

                IEdmComplexType actualType = model.FindType(complexValue.TypeName) as IEdmComplexType;
                if (actualType == null)
                {
                    throw new ODataException(Error.Format(SRResources.ComplexTypeNotInModel, complexValue.TypeName));
                }

                if (actualType.IsAbstract)
                {
                    string message = Error.Format(SRResources.CannotInstantiateAbstractComplexType,
                                                  complexValue.TypeName);
                    throw new ODataException(message);
                }

                IEdmTypeReference        actualComplexType = new EdmComplexTypeReference(actualType, isNullable: false);
                ODataEdmTypeDeserializer deserializer      = DeserializerProvider.GetEdmTypeDeserializer(actualComplexType);
                if (deserializer == null)
                {
                    throw new SerializationException(
                              Error.Format(SRResources.TypeCannotBeDeserialized, actualComplexType.FullName(),
                                           typeof(ODataMediaTypeFormatter).Name));
                }

                object resource = deserializer.ReadInline(complexValue, actualComplexType, readContext);

                EdmStructuredObject structuredObject = resource as EdmStructuredObject;
                if (structuredObject != null)
                {
                    structuredObject.ExpectedEdmType = complexType.ComplexDefinition();
                }

                return(resource);
            }
            else
            {
                object complexResource = CreateResource(complexType, readContext);

                foreach (ODataProperty complexProperty in complexValue.Properties)
                {
                    DeserializationHelpers.ApplyProperty(complexProperty, complexType, complexResource,
                                                         DeserializerProvider, readContext);
                }
                return(complexResource);
            }
        }
        public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
        {
            if (messageReader == null)
            {
                throw Error.ArgumentNull("messageReader");
            }

            IEdmAction action = GetAction(readContext);

            Contract.Assert(action != null);

            // Create the correct resource type;
            Dictionary <string, object> payload;

            if (type == typeof(ODataActionParameters))
            {
                payload = new ODataActionParameters();
            }
            else
            {
                payload = new ODataUntypedActionParameters(action);
            }

            ODataParameterReader reader = messageReader.CreateODataParameterReader(action);

            while (reader.Read())
            {
                string parameterName             = null;
                IEdmOperationParameter parameter = null;

                switch (reader.State)
                {
                case ODataParameterReaderState.Value:
                    parameterName = reader.Name;
                    parameter     = action.Parameters.SingleOrDefault(p => p.Name == parameterName);
                    // ODataLib protects against this but asserting just in case.
                    Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName));
                    if (parameter.Type.IsPrimitive())
                    {
                        payload[parameterName] = reader.Value;
                    }
                    else
                    {
                        ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(parameter.Type);
                        payload[parameterName] = deserializer.ReadInline(reader.Value, parameter.Type, readContext);
                    }
                    break;

                case ODataParameterReaderState.Collection:
                    parameterName = reader.Name;
                    parameter     = action.Parameters.SingleOrDefault(p => p.Name == parameterName);
                    // ODataLib protects against this but asserting just in case.
                    Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName));
                    IEdmCollectionTypeReference collectionType = parameter.Type as IEdmCollectionTypeReference;
                    Contract.Assert(collectionType != null);
                    ODataCollectionValue        value = ODataCollectionDeserializer.ReadCollection(reader.CreateCollectionReader());
                    ODataCollectionDeserializer collectionDeserializer = (ODataCollectionDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType);
                    payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext);
                    break;

                case ODataParameterReaderState.Resource:
                    parameterName = reader.Name;
                    parameter     = action.Parameters.SingleOrDefault(p => p.Name == parameterName);
                    Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName));
                    Contract.Assert(parameter.Type.IsStructured());

                    ODataReader resourceReader = reader.CreateResourceReader();
                    object      item           = resourceReader.ReadResourceOrResourceSet();
                    ODataResourceDeserializer resourceDeserializer = (ODataResourceDeserializer)DeserializerProvider.GetEdmTypeDeserializer(parameter.Type);
                    payload[parameterName] = resourceDeserializer.ReadInline(item, parameter.Type, readContext);
                    break;

                case ODataParameterReaderState.ResourceSet:
                    parameterName = reader.Name;
                    parameter     = action.Parameters.SingleOrDefault(p => p.Name == parameterName);
                    Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName));

                    IEdmCollectionTypeReference resourceSetType = parameter.Type as IEdmCollectionTypeReference;
                    Contract.Assert(resourceSetType != null);

                    ODataReader resourceSetReader = reader.CreateResourceSetReader();
                    object      feed = resourceSetReader.ReadResourceOrResourceSet();
                    ODataResourceSetDeserializer resourceSetDeserializer = (ODataResourceSetDeserializer)DeserializerProvider.GetEdmTypeDeserializer(resourceSetType);

                    object result = resourceSetDeserializer.ReadInline(feed, resourceSetType, readContext);

                    IEdmTypeReference elementTypeReference = resourceSetType.ElementType();
                    Contract.Assert(elementTypeReference.IsStructured());

                    IEnumerable enumerable = result as IEnumerable;
                    if (enumerable != null)
                    {
                        if (readContext.IsUntyped)
                        {
                            payload[parameterName] = enumerable.ConvertToEdmObject(resourceSetType);
                        }
                        else
                        {
                            Type        elementClrType = EdmLibHelpers.GetClrType(elementTypeReference, readContext.Model);
                            IEnumerable castedResult   =
                                _castMethodInfo.MakeGenericMethod(elementClrType)
                                .Invoke(null, new[] { result }) as IEnumerable;
                            payload[parameterName] = castedResult;
                        }
                    }
                    break;
                }
            }

            return(payload);
        }
        /// <inheritdoc />
        public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
        {
            if (messageReader == null)
            {
                throw Error.ArgumentNull("messageReader");
            }

            IEdmAction action = GetAction(readContext);

            Contract.Assert(action != null);

            // Create the correct resource type;
            Dictionary <string, object> payload;

            if (type == typeof(ODataActionParameters))
            {
                payload = new ODataActionParameters();
            }
            else
            {
                payload = new ODataUntypedActionParameters(action);
            }

            ODataParameterReader reader = messageReader.CreateODataParameterReader(action);

            while (reader.Read())
            {
                string parameterName             = null;
                IEdmOperationParameter parameter = null;

                switch (reader.State)
                {
                case ODataParameterReaderState.Value:
                    parameterName = reader.Name;
                    parameter     = action.Parameters.SingleOrDefault(p => p.Name == parameterName);
                    // ODataLib protects against this but asserting just in case.
                    Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName));
                    if (parameter.Type.IsPrimitive())
                    {
                        payload[parameterName] = reader.Value;
                    }
                    else
                    {
                        ODataEdmTypeDeserializer deserializer = DeserializerProvider.GetEdmTypeDeserializer(parameter.Type);
                        payload[parameterName] = deserializer.ReadInline(reader.Value, parameter.Type, readContext);
                    }
                    break;

                case ODataParameterReaderState.Collection:
                    parameterName = reader.Name;
                    parameter     = action.Parameters.SingleOrDefault(p => p.Name == parameterName);
                    // ODataLib protects against this but asserting just in case.
                    Contract.Assert(parameter != null, String.Format(CultureInfo.InvariantCulture, "Parameter '{0}' not found.", parameterName));
                    IEdmCollectionTypeReference collectionType = parameter.Type as IEdmCollectionTypeReference;
                    Contract.Assert(collectionType != null);
                    ODataCollectionValue        value = ODataCollectionDeserializer.ReadCollection(reader.CreateCollectionReader());
                    ODataCollectionDeserializer collectionDeserializer = (ODataCollectionDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType);
                    payload[parameterName] = collectionDeserializer.ReadInline(value, collectionType, readContext);
                    break;

                default:
                    break;
                }
            }

            return(payload);
        }