/// <inheritdoc />
        public override ODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw new ArgumentNullException(nameof(edmType));
            }

            switch (edmType.TypeKind())
            {
            case EdmTypeKind.Entity:
            case EdmTypeKind.Complex:
                return(_serviceProvider.GetRequiredService <ODataResourceDeserializer>());

            case EdmTypeKind.Enum:
                return(_serviceProvider.GetRequiredService <ODataEnumDeserializer>());

            case EdmTypeKind.Primitive:
                return(_serviceProvider.GetRequiredService <ODataPrimitiveDeserializer>());

            case EdmTypeKind.Collection:
                IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                if (collectionType.ElementType().IsEntity() || collectionType.ElementType().IsComplex())
                {
                    return(_serviceProvider.GetRequiredService <ODataResourceSetDeserializer>());
                }
                else
                {
                    return(_serviceProvider.GetRequiredService <ODataCollectionDeserializer>());
                }

            default:
                return(null);
            }
        }
Ejemplo n.º 2
0
        public void WriteObjectInline_WritesEachEntityInstance()
        {
            // Arrange
            var mockSerializerProvider = new Mock <ODataSerializerProvider>(MockBehavior.Strict, _model);
            var mockCustomerSerializer = new Mock <ODataSerializer>(MockBehavior.Strict, ODataPayloadKind.Entry);
            var mockWriter             = new Mock <ODataWriter>();

            mockSerializerProvider
            .Setup(p => p.CreateEdmTypeSerializer(_customersType.ElementType()))
            .Returns(mockCustomerSerializer.Object);
            mockCustomerSerializer
            .Setup(s => s.WriteObjectInline(_customers[0], It.IsAny <ODataWriter>(), _writeContext))
            .Verifiable();
            mockCustomerSerializer
            .Setup(s => s.WriteObjectInline(_customers[1], It.IsAny <ODataWriter>(), _writeContext))
            .Verifiable();
            mockWriter
            .Setup(w => w.WriteStart(It.IsAny <ODataFeed>()))
            .Callback((ODataFeed feed) =>
            {
                Assert.Equal("http://schemas.datacontract.org/2004/07/", feed.Id);
            })
            .Verifiable();

            _serializer = new ODataFeedSerializer(_customersType, mockSerializerProvider.Object);

            // Act
            _serializer.WriteObjectInline(_customers, mockWriter.Object, _writeContext);

            // Assert
            mockSerializerProvider.Verify();
            mockCustomerSerializer.Verify();
            mockWriter.Verify();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns the appropriate deserializer for the given IEdmType.
        ///
        /// The structure of this method is copied from DefaultODataDeserializerProvider, however the difference is
        /// that the Migration deserializers are hardwired in (use them all or use none of them).
        /// </summary>
        /// <param name="edmType">The edm type to obtain the deserializer for.</param>
        /// <returns>The appropriate deserializer for the given edm type.</returns>
        public override ODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw new ArgumentNullException(nameof(edmType));
            }

            switch (edmType.TypeKind())
            {
            case EdmTypeKind.Entity:
            case EdmTypeKind.Complex:
                // Resources might contain non-V3 compatible types,
                return(new ODataMigrationResourceDeserializer(this));

            case EdmTypeKind.Enum:
                return(new ODataEnumDeserializer());

            case EdmTypeKind.Primitive:
                return(new ODataPrimitiveDeserializer());

            case EdmTypeKind.Collection:
                IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                if (collectionType.ElementType().IsEntity() || collectionType.ElementType().IsComplex())
                {
                    return(new ODataResourceSetDeserializer(this));
                }
                else
                {
                    return(new ODataMigrationCollectionDeserializer(this));
                }

            default:
                return(null);
            }
        }
 public ODataFeedSerializer(IEdmCollectionTypeReference edmCollectionType, ODataSerializerProvider serializerProvider)
     : base(edmCollectionType, ODataPayloadKind.Feed, serializerProvider)
 {
     _edmCollectionType = edmCollectionType;
     if (!edmCollectionType.ElementType().IsEntity())
     {
         throw Error.NotSupported(SRResources.TypeMustBeEntityCollection, edmCollectionType.ElementType().FullName(), typeof(IEdmEntityType).Name);
     }
 }
Ejemplo n.º 5
0
 public ODataFeedSerializer(IEdmCollectionTypeReference edmCollectionType, ODataSerializerProvider serializerProvider)
     : base(edmCollectionType, ODataPayloadKind.Feed, serializerProvider)
 {
     _edmCollectionType = edmCollectionType;
     if (!edmCollectionType.ElementType().IsEntity())
     {
         throw Error.NotSupported(SRResources.TypeMustBeEntityCollection, edmCollectionType.ElementType().FullName(), typeof(IEdmEntityType).Name);
     }
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataFeedDeserializer"/> class.
        /// </summary>
        /// <param name="edmType">The entity collection type that this deserializer can read.</param>
        /// <param name="deserializerProvider">The deserializer provider to use to read inner objects.</param>
        public ODataFeedDeserializer(IEdmCollectionTypeReference edmType, ODataDeserializerProvider deserializerProvider)
            : base(edmType, ODataPayloadKind.Feed, deserializerProvider)
        {
            CollectionType = edmType;
            if (!edmType.ElementType().IsEntity())
            {
                throw Error.Argument("edmType", SRResources.TypeMustBeEntityCollection, edmType.ElementType().FullName(), typeof(IEdmEntityType).Name);
            }

            EntityType = CollectionType.ElementType().AsEntity();
        }
Ejemplo n.º 7
0
        private static object ConvertResourceSet(ODataMessageReader oDataMessageReader,
                                                 IEdmTypeReference edmTypeReference, ODataDeserializerContext readContext)
        {
            IEdmCollectionTypeReference collectionType = edmTypeReference.AsCollection();

            EdmEntitySet tempEntitySet = null;

            if (collectionType.ElementType().IsEntity())
            {
                tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp",
                                                 collectionType.ElementType().AsEntity().EntityDefinition());
            }

            // TODO: Sam xu, can we use the parameter-less overload
            ODataReader odataReader = oDataMessageReader.CreateODataUriParameterResourceSetReader(tempEntitySet,
                                                                                                  collectionType.ElementType().AsStructured().StructuredDefinition());
            ODataResourceSetWrapper resourceSet =
                odataReader.ReadResourceOrResourceSet() as ODataResourceSetWrapper;

            ODataDeserializerProvider deserializerProvider = readContext.Request.GetDeserializerProvider();

            ODataResourceSetDeserializer resourceSetDeserializer =
                (ODataResourceSetDeserializer)deserializerProvider.GetEdmTypeDeserializer(collectionType);

            object      result     = resourceSetDeserializer.ReadInline(resourceSet, collectionType, readContext);
            IEnumerable enumerable = result as IEnumerable;

            if (enumerable != null)
            {
                IEnumerable newEnumerable = enumerable;
                if (collectionType.ElementType().IsEntity())
                {
                    newEnumerable = CovertResourceSetIds(enumerable, resourceSet, collectionType, readContext);
                }

                if (readContext.IsUntyped)
                {
                    return(newEnumerable.ConvertToEdmObject(collectionType));
                }
                else
                {
                    IEdmTypeReference elementTypeReference = collectionType.ElementType();

                    Type elementClrType = EdmLibHelpers.GetClrType(elementTypeReference,
                                                                   readContext.Model);
                    IEnumerable castedResult =
                        CastMethodInfo.MakeGenericMethod(elementClrType)
                        .Invoke(null, new object[] { newEnumerable }) as IEnumerable;
                    return(castedResult);
                }
            }

            return(null);
        }
Ejemplo n.º 8
0
        private void Initialize(IEdmCollectionTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }
            if (!edmType.ElementType().IsComplex())
            {
                throw Error.Argument("edmType",
                                     SRResources.UnexpectedElementType, edmType.ElementType().ToTraceString(), edmType.ToTraceString(), typeof(IEdmComplexType).Name);
            }

            _edmType = edmType;
        }
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                return(null);
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            if (!edmType.IsCollection())
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeDeserialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter)));
            }

            IEdmCollectionTypeReference collectionType = edmType.AsCollection();
            IEdmTypeReference           elementType    = collectionType.ElementType();

            ODataCollectionValue collection = item as ODataCollectionValue;

            if (collection == null)
            {
                throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataCollectionValue).Name);
            }

            // Recursion guard to avoid stack overflows
            RuntimeHelpers.EnsureSufficientExecutionStack();

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

            IEdmTypeReference edmType = readContext.GetEdmType(type);

            Contract.Assert(edmType != null);

            if (!edmType.IsCollection())
            {
                throw Error.Argument("type", SRResources.ArgumentMustBeOfType, EdmTypeKind.Collection);
            }

            IEdmCollectionTypeReference collectionType = edmType.AsCollection();
            IEdmTypeReference           elementType    = collectionType.ElementType();

            IEnumerable result = ReadInline(ReadCollection(messageReader, elementType), edmType, readContext) as IEnumerable;

            if (result != null && readContext.IsUntyped && elementType.IsComplex())
            {
                EdmComplexObjectCollection complexCollection = new EdmComplexObjectCollection(collectionType);
                foreach (EdmComplexObject complexObject in result)
                {
                    complexCollection.Add(complexObject);
                }
                return(complexCollection);
            }

            return(result);
        }
Ejemplo n.º 11
0
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                return(null);
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            if (!edmType.IsCollection())
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeDeserialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter)));
            }

            IEdmCollectionTypeReference collectionType = edmType.AsCollection();
            IEdmTypeReference           elementType    = collectionType.ElementType();

            ODataCollectionValue collection = item as ODataCollectionValue;

            if (collection == null)
            {
                throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataCollectionValue).Name);
            }
            // Recursion guard to avoid stack overflows
            RuntimeHelpers.EnsureSufficientExecutionStack();

            IEnumerable result = ReadCollectionValue(collection, elementType, readContext);

            if (result != null)
            {
                if (readContext.IsUntyped && elementType.IsComplex())
                {
                    EdmComplexObjectCollection complexCollection = new EdmComplexObjectCollection(collectionType);
                    foreach (EdmComplexObject complexObject in result)
                    {
                        complexCollection.Add(complexObject);
                    }
                    return(complexCollection);
                }
                else if (readContext.IsUntyped && elementType.IsEnum())
                {
                    EdmEnumObjectCollection enumCollection = new EdmEnumObjectCollection(collectionType);
                    foreach (EdmEnumObject enumObject in result)
                    {
                        enumCollection.Add(enumObject);
                    }
                    return(enumCollection);
                }
                else
                {
                    Type        elementClrType = EdmLibHelpers.GetClrType(elementType, readContext.Model);
                    IEnumerable castedResult   = _castMethodInfo.MakeGenericMethod(elementClrType).Invoke(null, new object[] { result }) as IEnumerable;
                    return(castedResult);
                }
            }
            return(null);
        }
Ejemplo n.º 12
0
        protected override ODataEntryDeserializer CreateDeserializer(IEdmTypeReference edmType)
        {
            if (edmType != null)
            {
                switch (edmType.TypeKind())
                {
                case EdmTypeKind.Entity:
                    return(new ODataEntityDeserializer(edmType.AsEntity(), this));

                case EdmTypeKind.Primitive:
                    return(new ODataPrimitiveDeserializer(edmType.AsPrimitive()));

                case EdmTypeKind.Complex:
                    return(new ODataComplexTypeDeserializer(edmType.AsComplex(), this));

                case EdmTypeKind.Collection:
                    IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                    if (collectionType.ElementType().IsEntity())
                    {
                        return(new ODataFeedDeserializer(collectionType, this));
                    }
                    else
                    {
                        return(new ODataCollectionDeserializer(collectionType, this));
                    }
                }
            }

            return(null);
        }
        /// <inheritdoc />
        public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            switch (edmType.TypeKind())
            {
            case EdmTypeKind.Primitive:
                return(_primitiveSerializer);

            case EdmTypeKind.Collection:
                IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                if (collectionType.ElementType().IsEntity())
                {
                    return(_feedSerializer);
                }
                else
                {
                    return(_collectionSerializer);
                }

            case EdmTypeKind.Complex:
                return(_complexTypeSerializer);

            case EdmTypeKind.Entity:
                return(_entityTypeSerializer);

            default:
                return(null);
            }
        }
Ejemplo n.º 14
0
        public void ReadInline_Calls_ReadCollectionValue()
        {
            // Arrange
            Mock <ODataCollectionDeserializer> deserializer = new Mock <ODataCollectionDeserializer>(DeserializerProvider);
            ODataCollectionValue     collectionValue        = new ODataCollectionValue();
            ODataDeserializerContext readContext            = new ODataDeserializerContext();

            deserializer.CallBase = true;
            deserializer.Setup(s => s.ReadCollectionValue(collectionValue, IntCollectionType.ElementType(), readContext)).Verifiable();

            // Act
            deserializer.Object.ReadInline(collectionValue, IntCollectionType, readContext);

            // Assert
            deserializer.Verify();
        }
        public override ODataSerializer CreateEdmTypeSerializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            switch (edmType.TypeKind())
            {
            case EdmTypeKind.Primitive:
                return(new ODataPrimitiveSerializer(edmType.AsPrimitive()));

            case EdmTypeKind.Collection:
                IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                if (collectionType.ElementType().IsEntity())
                {
                    return(new ODataFeedSerializer(collectionType, this));
                }
                else
                {
                    return(new ODataCollectionSerializer(collectionType, this));
                }

            case EdmTypeKind.Complex:
                return(new ODataComplexTypeSerializer(edmType.AsComplex(), this));

            case EdmTypeKind.Entity:
                return(new ODataEntityTypeSerializer(edmType.AsEntity(), this));

            default:
                throw Error.InvalidOperation(SRResources.TypeCannotBeSerialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter).Name);
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Gets the parameter value.
        /// </summary>
        /// <param name="parameterName">The name of the parameter.</param>
        /// <returns> The value of the parameter. </returns>
        public object GetParameterValue(string parameterName)
        {
            if (String.IsNullOrEmpty(parameterName))
            {
                throw Error.ArgumentNullOrEmpty("parameterName");
            }

            string paramValue;

            if (Values.TryGetValue(parameterName, out paramValue))
            {
                IEdmOperationParameter edmParam = Function.FindParameter(parameterName);
                if (edmParam != null)
                {
                    IEdmTypeReference edmType = edmParam.Type;
                    if (edmParam.Type.IsCollection())
                    {
                        IEdmCollectionTypeReference collectionTypeReference = edmParam.Type.AsCollection();
                        edmType = collectionTypeReference.ElementType();
                    }

                    // for entity or collection of entity, return the string literal from Uri.
                    if (edmType.Definition.TypeKind == EdmTypeKind.Entity)
                    {
                        return(paramValue);
                    }

                    return(ODataUriUtils.ConvertFromUriLiteral(paramValue, ODataVersion.V4, _edmModel, edmParam.Type));
                }
            }

            throw Error.Argument("parameterName", SRResources.FunctionParameterNotFound, parameterName);
        }
        private static void ProcessResourceSet(object feed, IEdmCollectionTypeReference resourceSetType, ODataDeserializerContext readContext, ODataDeserializerProvider deserializerProvider, Dictionary <string, object> payload, string parameterName)
        {
            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;
                }
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Creates an <see cref="ODataEdmTypeDeserializer"/> that can deserialize payloads of the given <paramref name="edmType"/>.
        /// </summary>
        /// <param name="edmType">The EDM type that the created deserializer can handle.</param>
        /// <returns>The created deserializer.</returns>
        /// <remarks> Override this method if you want to use a custom deserializer. <see cref="GetEdmTypeDeserializer"/> calls into this method and caches the result.</remarks>
        public virtual ODataEdmTypeDeserializer CreateEdmTypeDeserializer(IEdmTypeReference edmType)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            switch (edmType.TypeKind())
            {
            case EdmTypeKind.Entity:
                return(new ODataEntityDeserializer(edmType.AsEntity(), this));

            case EdmTypeKind.Primitive:
                return(new ODataPrimitiveDeserializer(edmType.AsPrimitive()));

            case EdmTypeKind.Complex:
                return(new ODataComplexTypeDeserializer(edmType.AsComplex(), this));

            case EdmTypeKind.Collection:
                IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                if (collectionType.ElementType().IsEntity())
                {
                    return(new ODataFeedDeserializer(collectionType, this));
                }
                else
                {
                    return(new ODataCollectionDeserializer(collectionType, this));
                }

            default:
                return(null);
            }
        }
Ejemplo n.º 19
0
        /// <inheritdoc />
        public override async Task <object> ReadAsync(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
        {
            if (messageReader == null)
            {
                throw Error.ArgumentNull("messageReader");
            }

            if (readContext == null)
            {
                throw new ArgumentNullException(nameof(readContext));
            }

            IEdmTypeReference edmType = readContext.GetEdmType(type);

            Contract.Assert(edmType != null);

            if (!edmType.IsCollection())
            {
                throw Error.Argument("type", SRResources.ArgumentMustBeOfType, EdmTypeKind.Collection);
            }

            IEdmCollectionTypeReference collectionType = edmType.AsCollection();
            IEdmTypeReference           elementType    = collectionType.ElementType();
            ODataCollectionReader       reader         = await messageReader.CreateODataCollectionReaderAsync(elementType).ConfigureAwait(false);

            return(ReadInline(await ReadCollectionAsync(reader).ConfigureAwait(false), edmType, readContext));
        }
Ejemplo n.º 20
0
            internal static object ConvertFeed(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference, ODataDeserializerContext readContext)
            {
                IEdmCollectionTypeReference collectionType = edmTypeReference.AsCollection();

                EdmEntitySet tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp",
                                                              collectionType.ElementType().AsEntity().EntityDefinition());

                ODataReader odataReader = oDataMessageReader.CreateODataFeedReader(tempEntitySet,
                                                                                   collectionType.ElementType().AsEntity().EntityDefinition());
                ODataFeedWithEntries feed =
                    ODataEntityDeserializer.ReadEntryOrFeed(odataReader) as ODataFeedWithEntries;

                ODataFeedDeserializer feedDeserializer =
                    (ODataFeedDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType);

                object      result     = feedDeserializer.ReadInline(feed, collectionType, readContext);
                IEnumerable enumerable = result as IEnumerable;

                if (enumerable != null)
                {
                    IEnumerable newEnumerable = CovertFeedIds(enumerable, feed, collectionType, readContext);
                    if (readContext.IsUntyped)
                    {
                        EdmEntityObjectCollection entityCollection =
                            new EdmEntityObjectCollection(collectionType);
                        foreach (EdmEntityObject entity in newEnumerable)
                        {
                            entityCollection.Add(entity);
                        }

                        return(entityCollection);
                    }
                    else
                    {
                        IEdmTypeReference elementTypeReference = collectionType.ElementType();

                        Type elementClrType = EdmLibHelpers.GetClrType(elementTypeReference,
                                                                       readContext.Model);
                        IEnumerable castedResult =
                            CastMethodInfo.MakeGenericMethod(elementClrType)
                            .Invoke(null, new object[] { newEnumerable }) as IEnumerable;
                        return(castedResult);
                    }
                }

                return(null);
            }
        public void GetEdmType_Returns_EdmTypeInitializedByCtor()
        {
            IEdmEntityType _entityType = new EdmEntityType("NS", "Entity");
            var            edmObject   = new EdmChangedObjectCollection(_entityType);
            IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)edmObject.GetEdmType();

            Assert.Same(_entityType, collectionTypeReference.ElementType().Definition);
        }
        internal void WriteCollectionValue(ODataCollectionValue collectionValue, IEdmTypeReference metadataTypeReference, bool isOpenPropertyType)
        {
            this.IncreaseRecursionDepth();
            base.JsonWriter.StartObjectScope();
            string typeName = collectionValue.TypeName;
            IEdmCollectionTypeReference type  = (IEdmCollectionTypeReference)WriterValidationUtils.ResolveTypeNameForWriting(base.Model, metadataTypeReference, ref typeName, EdmTypeKind.Collection, isOpenPropertyType);
            string itemTypeNameFromCollection = null;

            if (typeName != null)
            {
                itemTypeNameFromCollection = ValidationUtils.ValidateCollectionTypeName(typeName);
            }
            SerializationTypeNameAnnotation annotation = collectionValue.GetAnnotation <SerializationTypeNameAnnotation>();

            if (annotation != null)
            {
                typeName = annotation.TypeName;
            }
            if (typeName != null)
            {
                base.JsonWriter.WriteName("__metadata");
                base.JsonWriter.StartObjectScope();
                base.JsonWriter.WriteName("type");
                base.JsonWriter.WriteValue(typeName);
                base.JsonWriter.EndObjectScope();
            }
            base.JsonWriter.WriteDataArrayName();
            base.JsonWriter.StartArrayScope();
            IEnumerable items = collectionValue.Items;

            if (items != null)
            {
                IEdmTypeReference propertyTypeReference = (type == null) ? null : type.ElementType();
                CollectionWithoutExpectedTypeValidator collectionValidator           = new CollectionWithoutExpectedTypeValidator(itemTypeNameFromCollection);
                DuplicatePropertyNamesChecker          duplicatePropertyNamesChecker = null;
                foreach (object obj2 in items)
                {
                    ValidationUtils.ValidateCollectionItem(obj2, false);
                    ODataComplexValue complexValue = obj2 as ODataComplexValue;
                    if (complexValue != null)
                    {
                        if (duplicatePropertyNamesChecker == null)
                        {
                            duplicatePropertyNamesChecker = base.CreateDuplicatePropertyNamesChecker();
                        }
                        this.WriteComplexValue(complexValue, propertyTypeReference, false, duplicatePropertyNamesChecker, collectionValidator);
                        duplicatePropertyNamesChecker.Clear();
                    }
                    else
                    {
                        this.WritePrimitiveValue(obj2, collectionValidator, propertyTypeReference);
                    }
                }
            }
            base.JsonWriter.EndArrayScope();
            base.JsonWriter.EndObjectScope();
            this.DecreaseRecursionDepth();
        }
        /// <inheritdoc />
        public ODataEdmTypeSerializer GetEdmTypeSerializer(HttpContext context, IEdmTypeReference edmType)
        {
            if (context == null)
            {
                throw Error.ArgumentNull("context");
            }

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

            IServiceProvider provider = context.RequestServices;

            switch (edmType.TypeKind())
            {
            case EdmTypeKind.Enum:
                return(provider.GetRequiredService <ODataEnumSerializer>());

            case EdmTypeKind.Primitive:
                return(provider.GetRequiredService <ODataPrimitiveSerializer>());

            case EdmTypeKind.Collection:
                IEdmCollectionTypeReference collectionType = edmType.AsCollection();
                if (collectionType.Definition.IsDeltaFeed())
                {
                    return(provider.GetRequiredService <ODataDeltaFeedSerializer>());
                }
                else if (collectionType.ElementType().IsEntity() || collectionType.ElementType().IsComplex())
                {
                    return(provider.GetRequiredService <ODataResourceSetSerializer>());
                }
                else
                {
                    return(provider.GetRequiredService <ODataCollectionSerializer>());
                }

            case EdmTypeKind.Complex:
            case EdmTypeKind.Entity:
                return(provider.GetRequiredService <ODataResourceSerializer>());

            default:
                return(null);
            }
        }
        public void WriteObjectInline_WritesEachEntityInstance()
        {
            // Arrange
            Mock <ODataEdmTypeSerializer> customerSerializer = new Mock <ODataEdmTypeSerializer>(ODataPayloadKind.Entry);
            ODataSerializerProvider       provider           = ODataTestUtil.GetMockODataSerializerProvider(customerSerializer.Object);
            var mockWriter = new Mock <ODataWriter>();

            customerSerializer.Setup(s => s.WriteObjectInline(_customers[0], _customersType.ElementType(), mockWriter.Object, _writeContext)).Verifiable();
            customerSerializer.Setup(s => s.WriteObjectInline(_customers[1], _customersType.ElementType(), mockWriter.Object, _writeContext)).Verifiable();

            _serializer = new ODataFeedSerializer(provider);

            // Act
            _serializer.WriteObjectInline(_customers, _customersType, mockWriter.Object, _writeContext);

            // Assert
            customerSerializer.Verify();
        }
 public ODataCollectionSerializer(IEdmCollectionTypeReference edmCollectionType, ODataSerializerProvider serializerProvider)
     : base(edmCollectionType, ODataPayloadKind.Collection, serializerProvider)
 {
     Contract.Assert(edmCollectionType != null);
     _edmCollectionType = edmCollectionType;
     IEdmTypeReference itemType = edmCollectionType.ElementType();
     Contract.Assert(itemType != null);
     _edmItemType = itemType;
 }
        public static IEdmTypeReference GetElementTypeOrSelf(this IEdmTypeReference typeReference)
        {
            if (typeReference.TypeKind() == EdmTypeKind.Collection)
            {
                IEdmCollectionTypeReference collectType = typeReference.AsCollection();
                return(collectType.ElementType());
            }

            return(typeReference);
        }
Ejemplo n.º 27
0
        internal static IEdmTypeReference GetCollectionItemType(this IEdmTypeReference typeReference)
        {
            IEdmCollectionTypeReference type = typeReference.AsCollectionOrNull();

            if (type != null)
            {
                return(type.ElementType());
            }
            return(null);
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataFeedDeserializer"/> class.
        /// </summary>
        /// <param name="edmType">The entity collection type that this deserializer can read.</param>
        /// <param name="deserializerProvider">The deserializer provider to use to read inner objects.</param>
        public ODataFeedDeserializer(IEdmCollectionTypeReference edmType, ODataDeserializerProvider deserializerProvider)
            : base(edmType, ODataPayloadKind.Feed, deserializerProvider)
        {
            CollectionType = edmType;
            if (!edmType.ElementType().IsEntity())
            {
                throw Error.Argument("edmType", SRResources.TypeMustBeEntityCollection, edmType.ElementType().FullName(), typeof(IEdmEntityType).Name);
            }

            EntityType = CollectionType.ElementType().AsEntity();
        }
        private void WriteFeed(object graph, ODataWriter writer, ODataSerializerContext writeContext)
        {
            ODataSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(_edmCollectionType.ElementType());

            if (entrySerializer == null)
            {
                throw Error.NotSupported(SRResources.TypeCannotBeSerialized, _edmCollectionType.ElementType(), typeof(ODataMediaTypeFormatter).Name);
            }

            Contract.Assert(entrySerializer.ODataPayloadKind == ODataPayloadKind.Entry);

            IEnumerable enumerable = graph as IEnumerable; // Data to serialize

            if (enumerable != null)
            {
                ODataFeed feed = new ODataFeed();

                if (writeContext.EntitySet != null)
                {
                    IEntitySetLinkBuilder linkBuilder = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet);
                    Uri feedSelfLink = linkBuilder.BuildFeedSelfLink(new FeedContext(writeContext.EntitySet, writeContext.UrlHelper, graph));
                    if (feedSelfLink != null)
                    {
                        feed.SetAnnotation(new AtomFeedMetadata()
                        {
                            SelfLink = new AtomLinkMetadata()
                            {
                                Relation = SelfLinkRelation, Href = feedSelfLink
                            }
                        });
                    }
                }

                // TODO: Bug 467590: remove the hardcoded feed id. Get support for it from the model builder ?
                feed.Id = FeedNamespace + _edmCollectionType.FullName();

                // If we have more OData format specific information apply it now.
                ODataResult odataFeedAnnotations = graph as ODataResult;
                if (odataFeedAnnotations != null)
                {
                    feed.Count        = odataFeedAnnotations.Count;
                    feed.NextPageLink = odataFeedAnnotations.NextPageLink;
                }

                writer.WriteStart(feed);

                foreach (object entry in enumerable)
                {
                    entrySerializer.WriteObjectInline(entry, writer, writeContext);
                }

                writer.WriteEnd();
            }
        }
Ejemplo n.º 30
0
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                return(null);
            }

            if (edmType == null)
            {
                throw new ArgumentNullException(nameof(edmType));
            }

            if (readContext == null)
            {
                throw new ArgumentNullException(nameof(readContext));
            }

            if (!edmType.IsCollection())
            {
                throw new SerializationException(
                          Error.Format(SRResources.TypeCannotBeDeserialized, edmType.ToTraceString()));
            }

            IEdmCollectionTypeReference collectionType = edmType.AsCollection();
            IEdmTypeReference           elementType    = collectionType.ElementType();

            ODataCollectionValue collection = item as ODataCollectionValue;

            if (collection == null)
            {
                throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataCollectionValue).Name);
            }
            // Recursion guard to avoid stack overflows
            RuntimeHelpers.EnsureSufficientExecutionStack();

            IEnumerable result = ReadCollectionValue(collection, elementType, readContext);

            if (result != null)
            {
                if (readContext.IsNoClrType && elementType.IsEnum())
                {
                    return(result.ConvertToEdmObject(collectionType));
                }
                else
                {
                    Type        elementClrType = readContext.Model.GetClrType(elementType);
                    IEnumerable castedResult   = _castMethodInfo.MakeGenericMethod(elementClrType).Invoke(null, new object[] { result }) as IEnumerable;
                    return(castedResult);
                }
            }

            return(null);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataCollectionSerializer"/> class.
        /// </summary>
        /// <param name="edmType">The edm collection type this serializer instance can serialize.</param>
        /// <param name="serializerProvider">The serializer provider to use to serialize nested objects.</param>
        public ODataCollectionSerializer(IEdmCollectionTypeReference edmType, ODataSerializerProvider serializerProvider)
            : base(edmType, ODataPayloadKind.Collection, serializerProvider)
        {
            IEdmTypeReference itemType = edmType.ElementType();
            if (itemType == null)
            {
                throw Error.Argument("edmType", SRResources.ItemTypeOfCollectionNull, edmType.FullName());
            }

            CollectionType = edmType;
            ElementType = itemType;
        }
Ejemplo n.º 32
0
            internal static IEnumerable CovertFeedIds(IEnumerable sources, ODataFeedWithEntries feed,
                                                      IEdmCollectionTypeReference collectionType, ODataDeserializerContext readContext)
            {
                IEdmEntityTypeReference entityTypeReference = collectionType.ElementType().AsEntity();
                int i = 0;

                foreach (object item in sources)
                {
                    object newItem = CovertEntityId(item, feed.Entries[i].Entry, entityTypeReference, readContext);
                    i++;
                    yield return(newItem);
                }
            }
Ejemplo n.º 33
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataCollectionSerializer"/> class.
        /// </summary>
        /// <param name="edmType">The edm collection type this serializer instance can serialize.</param>
        /// <param name="serializerProvider">The serializer provider to use to serialize nested objects.</param>
        public ODataCollectionSerializer(IEdmCollectionTypeReference edmType, ODataSerializerProvider serializerProvider)
            : base(edmType, ODataPayloadKind.Collection, serializerProvider)
        {
            IEdmTypeReference itemType = edmType.ElementType();

            if (itemType == null)
            {
                throw Error.Argument("edmType", SRResources.ItemTypeOfCollectionNull, edmType.FullName());
            }

            CollectionType = edmType;
            ElementType    = itemType;
        }
Ejemplo n.º 34
0
        public void ClrBasedCollectionsAreNullableByDefault()
        {
            IEdmModel    model          = StaticModel.BuildModel();
            var          indexType      = (IEdmEntityType)model.FindDeclaredType(typeof(Index).FullName);
            IEdmProperty fieldsProperty = indexType.FindProperty(nameof(Index.Fields));

            Assert.AreEqual(true, fieldsProperty.Type.IsCollection());

            IEdmCollectionTypeReference collectionType = fieldsProperty.Type.AsCollection();

            Assert.AreEqual(true, collectionType.IsNullable);
            Assert.AreEqual(true, collectionType.ElementType().IsNullable);
        }
        public ODataFeedSerializer(IEdmCollectionTypeReference edmCollectionType, ODataSerializerProvider serializerProvider)
            : base(edmCollectionType, ODataPayloadKind.Feed, serializerProvider)
        {
            Contract.Assert(edmCollectionType != null);
            _edmCollectionType = edmCollectionType;
            if (!edmCollectionType.ElementType().IsEntity())
            {
                throw Error.NotSupported(SRResources.TypeMustBeEntityCollection, edmCollectionType.ElementType().FullName(), typeof(IEdmEntityType).Name);
            }

            Contract.Assert(edmCollectionType.ElementType() != null);
            Contract.Assert(edmCollectionType.ElementType().AsEntity() != null);
            Contract.Assert(edmCollectionType.ElementType().AsEntity().Definition != null);
            Contract.Assert(edmCollectionType.ElementType().AsEntity().Definition as IEdmEntityType != null);
            _edmElementType = _edmCollectionType.ElementType().AsEntity().Definition as IEdmEntityType;
        }
        private ODataCollectionValue ReadCollectionValue(IEdmCollectionTypeReference collectionTypeReference, string payloadTypeName, SerializationTypeNameAnnotation serializationTypeNameAnnotation)
        {
            this.IncreaseRecursionDepth();
            ODataCollectionValue value2 = new ODataCollectionValue {
                TypeName = (collectionTypeReference == null) ? payloadTypeName : collectionTypeReference.ODataFullName()
            };
            if (serializationTypeNameAnnotation != null)
            {
                value2.SetAnnotation<SerializationTypeNameAnnotation>(serializationTypeNameAnnotation);
            }
            base.XmlReader.MoveToElement();
            List<object> sourceEnumerable = new List<object>();
            if (!base.XmlReader.IsEmptyElement)
            {
                base.XmlReader.ReadStartElement();
                IEdmTypeReference expectedTypeReference = (collectionTypeReference == null) ? null : collectionTypeReference.ElementType();
                DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = base.CreateDuplicatePropertyNamesChecker();
                CollectionWithoutExpectedTypeValidator collectionValidator = null;
                if (collectionTypeReference == null)
                {
                    string itemTypeNameFromCollection = (payloadTypeName == null) ? null : EdmLibraryExtensions.GetCollectionItemTypeName(payloadTypeName);
                    collectionValidator = new CollectionWithoutExpectedTypeValidator(itemTypeNameFromCollection);
                }
                do
                {
                    switch (base.XmlReader.NodeType)
                    {
                        case XmlNodeType.Element:
                            if (base.XmlReader.NamespaceEquals(base.XmlReader.ODataNamespace))
                            {
                                if (!base.XmlReader.LocalNameEquals(this.ODataCollectionItemElementName))
                                {
                                    throw new ODataException(Microsoft.Data.OData.Strings.ODataAtomPropertyAndValueDeserializer_InvalidCollectionElement(base.XmlReader.LocalName, base.XmlReader.ODataNamespace));
                                }
                                object item = this.ReadNonEntityValueImplementation(expectedTypeReference, duplicatePropertyNamesChecker, collectionValidator, true, false);
                                base.XmlReader.Read();
                                ValidationUtils.ValidateCollectionItem(item, false);
                                sourceEnumerable.Add(item);
                            }
                            else
                            {
                                base.XmlReader.Skip();
                            }
                            break;

                        case XmlNodeType.EndElement:
                            break;

                        default:
                            base.XmlReader.Skip();
                            break;
                    }
                }
                while (base.XmlReader.NodeType != XmlNodeType.EndElement);
            }
            value2.Items = new ReadOnlyEnumerable(sourceEnumerable);
            this.DecreaseRecursionDepth();
            return value2;
        }
 internal static IEnumerable CovertFeedIds(IEnumerable sources, ODataFeedWithEntries feed,
     IEdmCollectionTypeReference collectionType, ODataDeserializerContext readContext)
 {
     IEdmEntityTypeReference entityTypeReference = collectionType.ElementType().AsEntity();
     int i = 0;
     foreach (object item in sources)
     {
         object newItem = CovertEntityId(item, feed.Entries[i].Entry, entityTypeReference, readContext);
         i++;
         yield return newItem;
     }
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataCollectionDeserializer"/> class.
 /// </summary>
 /// <param name="edmType">The collection type that this deserializer can read.</param>
 /// <param name="deserializerProvider">The deserializer provider to use to read inner objects.</param>
 public ODataCollectionDeserializer(IEdmCollectionTypeReference edmType, ODataDeserializerProvider deserializerProvider)
     : base(edmType, ODataPayloadKind.Collection, deserializerProvider)
 {
     CollectionType = edmType;
     ElementType = edmType.ElementType();
 }
        /// <summary>
        /// Read a collection from the reader.
        /// </summary>
        /// <param name="collectionTypeReference">The type of the collection to read (or null if no type is available).</param>
        /// <param name="payloadTypeName">The name of the collection type specified in the payload.</param>
        /// <param name="serializationTypeNameAnnotation">The serialization type name for the collection value (possibly null).</param>
        /// <returns>The value read from the payload.</returns>
        /// <remarks>
        /// Pre-Condition:   XmlNodeType.Element   - the element to read the value for.
        ///                  XmlNodeType.Attribute - an attribute on the element to read the value for.
        /// Post-Condition:  XmlNodeType.Element    - the element was empty.
        ///                  XmlNodeType.EndElement - the element had some value.
        ///                  
        /// Note that this method will not read null values, those should be handled by the caller already.
        /// </remarks>
        private ODataCollectionValue ReadCollectionValue(
            IEdmCollectionTypeReference collectionTypeReference, 
            string payloadTypeName,
            SerializationTypeNameAnnotation serializationTypeNameAnnotation)
        {
            this.AssertXmlCondition(XmlNodeType.Element, XmlNodeType.Attribute);
            Debug.Assert(
                collectionTypeReference == null || collectionTypeReference.IsNonEntityCollectionType(),
                "If the metadata is specified it must denote a collection for this method to work.");

            this.IncreaseRecursionDepth();

            ODataCollectionValue collectionValue = new ODataCollectionValue();

            // If we have a metadata type for the collection, use that type name
            // otherwise use the type name from the payload (if there was any).
            collectionValue.TypeName = collectionTypeReference == null ? payloadTypeName : collectionTypeReference.ODataFullName();
            if (serializationTypeNameAnnotation != null)
            {
                collectionValue.SetAnnotation(serializationTypeNameAnnotation);
            }

            // Move to the element (so that if we were on an attribute we can test the element for being empty)
            this.XmlReader.MoveToElement();

            List<object> items = new List<object>();

            // Empty collections are valid - they have no items
            if (!this.XmlReader.IsEmptyElement)
            {
                // Read over the collection element to its first child node (or end-element)
                this.XmlReader.ReadStartElement();

                // If we don't have metadata (that is collectionType is null) we parse the type name
                // and extract the item type name from it. Then we create a CollectionWithoutExpectedTypeValidator
                // instance and use it to ensure that all item types read for the collection value are consistent with
                // the item type derived from the collection value's type name.
                // Note that if an item does not specify a type name but the collection value does, the item will be
                // assigned the item type name computed from the collection value's type.
                // Note that JSON doesn't have this problem since in JSON we always have metadata and thus the collectionType
                // is never null by the time we get to a similar place in the code.
                IEdmTypeReference itemTypeReference = collectionTypeReference == null ? null : collectionTypeReference.ElementType();

                DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker();
                CollectionWithoutExpectedTypeValidator collectionValidator = null;
                if (collectionTypeReference == null)
                {
                    // Parse the type name from the payload (if any), extract the item type name and construct a collection validator
                    string itemTypeName = payloadTypeName == null ? null : EdmLibraryExtensions.GetCollectionItemTypeName(payloadTypeName);
                    collectionValidator = new CollectionWithoutExpectedTypeValidator(itemTypeName);
                }

                do
                {
                    switch (this.XmlReader.NodeType)
                    {
                        case XmlNodeType.Element:
                            if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataMetadataNamespace))
                            {
                                if (!this.XmlReader.LocalNameEquals(this.ODataCollectionItemElementName))
                                {
                                    this.XmlReader.Skip();
                                }
                                else
                                {
                                    object itemValue = this.ReadNonEntityValueImplementation(
                                        itemTypeReference,
                                        duplicatePropertyNamesChecker,
                                        collectionValidator,
                                        /*validateNullValue*/ true,
                                        /*propertyName*/ null);

                                    // read over the end tag of the element or the start tag if the element was empty.
                                    this.XmlReader.Read();

                                    // Validate the item (for example that it's not null)
                                    ValidationUtils.ValidateCollectionItem(itemValue, itemTypeReference.IsNullable());

                                    // Note that the ReadNonEntityValue already validated that the actual type of the value matches
                                    // the expected type (the itemType).
                                    items.Add(itemValue);
                                }
                            }
                            else if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace))
                            {
                                throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueDeserializer_InvalidCollectionElement(this.XmlReader.LocalName, this.XmlReader.ODataMetadataNamespace));  
                            }
                            else
                            {
                                this.XmlReader.Skip();
                            }

                            break;

                        case XmlNodeType.EndElement:
                            // End of the collection.
                            break;

                        default:
                            // Non-element so for example a text node, just ignore
                            this.XmlReader.Skip();
                            break;
                    }
                }
                while (this.XmlReader.NodeType != XmlNodeType.EndElement);
            }

            collectionValue.Items = new ReadOnlyEnumerable(items);

            this.AssertXmlCondition(true, XmlNodeType.EndElement);
            Debug.Assert(collectionValue != null, "The method should never return null since it doesn't handle null values.");

            this.DecreaseRecursionDepth();

            return collectionValue;
        }
        private object Convert(ODataCollectionReader reader, IEdmCollectionTypeReference collectionType, ODataDeserializerContext readContext)
        {
            IEdmTypeReference elementType = collectionType.ElementType();
            Type clrElementType = EdmLibHelpers.GetClrType(elementType, readContext.Model);
            IList list = Activator.CreateInstance(typeof(List<>).MakeGenericType(clrElementType)) as IList;

            while (reader.Read())
            {
                switch (reader.State)
                {
                    case ODataCollectionReaderState.Value:
                        object element = Convert(reader.Item, elementType, readContext);
                        list.Add(element);
                        break;

                    default:
                        break;
                }
            }
            return list;
        }
Ejemplo n.º 41
0
        internal static void SetDynamicCollectionProperty(object resource, string propertyName, object value,
            IEdmCollectionTypeReference edmPropertyType, IEdmStructuredType structuredType,
            ODataDeserializerContext readContext, AssembliesResolver assembliesResolver)
        {
            Contract.Assert(value != null);
            Contract.Assert(readContext != null);
            Contract.Assert(readContext.Model != null);

            IEnumerable collection = value as IEnumerable;
            Contract.Assert(collection != null);

            Type resourceType = resource.GetType();
            Type elementType = EdmLibHelpers.GetClrType(edmPropertyType.ElementType(), readContext.Model, assembliesResolver);
            Type propertyType = typeof(ICollection<>).MakeGenericType(elementType);
            IEnumerable newCollection;
            if (CollectionDeserializationHelpers.TryCreateInstance(propertyType, edmPropertyType, elementType,
                out newCollection))
            {
                collection.AddToCollection(newCollection, elementType, resourceType, propertyName, propertyType, assembliesResolver);
                SetDynamicProperty(resource, propertyName, newCollection, structuredType, readContext);
            }
        }