public void ReadEntry_SetsExpectedAndActualEdmType_OnCreatedEdmObject_TypelessMode()
        {
            // Arrange
            CustomersModelWithInheritance model        = new CustomersModelWithInheritance();
            IEdmEntityTypeReference       customerType = EdmLibHelpers.ToEdmTypeReference(model.Customer, isNullable: false).AsEntity();
            ODataDeserializerContext      readContext  = new ODataDeserializerContext {
                Model = model.Model, ResourceType = typeof(IEdmObject)
            };
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry
            {
                TypeName   = model.SpecialCustomer.FullName(),
                Properties = new ODataProperty[0]
            });

            ODataEntityDeserializer deserializer = new ODataEntityDeserializer(_deserializerProvider);

            // Act
            var result = deserializer.ReadEntry(entry, customerType, readContext);

            // Assert
            EdmEntityObject resource = Assert.IsType <EdmEntityObject>(result);

            Assert.Equal(model.SpecialCustomer, resource.ActualEdmType);
            Assert.Equal(model.Customer, resource.ExpectedEdmType);
        }
Esempio n. 2
0
        /// <inheritdoc />
        public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext)
        {
            if (item == null)
            {
                throw Error.ArgumentNull("item");
            }
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }
            if (!edmType.IsEntity())
            {
                throw Error.Argument("edmType", SRResources.ArgumentMustBeOfType, EdmTypeKind.Entity);
            }

            ODataEntryWithNavigationLinks entryWrapper = item as ODataEntryWithNavigationLinks;

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

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

            return(ReadEntry(entryWrapper, edmType.AsEntity(), readContext));
        }
Esempio n. 3
0
        /// <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);
            }
        }
        public void ReadEntry_ThrowsArgumentNull_ReadContext()
        {
            var deserializer = new ODataEntityDeserializer(_deserializerProvider);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry());

            Assert.ThrowsArgumentNull(
                () => deserializer.ReadEntry(entry, entityType: _productEdmType, readContext: null),
                "readContext");
        }
        public void ReadEntry_ThrowsODataException_EntityTypeNotInModel()
        {
            var deserializer = new ODataEntityDeserializer(_deserializerProvider);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry {
                TypeName = "MissingType"
            });

            Assert.Throws <ODataException>(
                () => deserializer.ReadEntry(entry, _productEdmType, _readContext),
                "Cannot find the entity type 'MissingType' in the model.");
        }
        public void ReadEntry_ThrowsArgument_ModelMissingFromReadContext()
        {
            var deserializer = new ODataEntityDeserializer(_deserializerProvider);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry {
                TypeName = _supplierEdmType.FullName()
            });

            Assert.ThrowsArgument(
                () => deserializer.ReadEntry(entry, _productEdmType, new ODataDeserializerContext()),
                "readContext",
                "The EDM model is missing on the read context. The model is required on the read context to deserialize the payload.");
        }
Esempio n. 7
0
        /// <summary>
        /// Deserializes the structural properties from <paramref name="entryWrapper"/> into <paramref name="entityResource"/>.
        /// </summary>
        /// <param name="entityResource">The object into which the structural properties should be read.</param>
        /// <param name="entryWrapper">The entry object containing the structural properties.</param>
        /// <param name="entityType">The entity type of the entity resource.</param>
        /// <param name="readContext">The deserializer context.</param>
        public virtual void ApplyStructuralProperties(object entityResource, ODataEntryWithNavigationLinks entryWrapper,
                                                      IEdmEntityTypeReference entityType, ODataDeserializerContext readContext)
        {
            if (entryWrapper == null)
            {
                throw Error.ArgumentNull("entryWrapper");
            }

            foreach (ODataProperty property in entryWrapper.Entry.Properties)
            {
                ApplyStructuralProperty(entityResource, property, entityType, readContext);
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Deserializes the navigation properties from <paramref name="entryWrapper"/> into <paramref name="entityResource"/>.
        /// </summary>
        /// <param name="entityResource">The object into which the navigation properties should be read.</param>
        /// <param name="entryWrapper">The entry object containing the navigation properties.</param>
        /// <param name="entityType">The entity type of the entity resource.</param>
        /// <param name="readContext">The deserializer context.</param>
        public virtual void ApplyNavigationProperties(object entityResource, ODataEntryWithNavigationLinks entryWrapper,
                                                      IEdmEntityTypeReference entityType, ODataDeserializerContext readContext)
        {
            if (entryWrapper == null)
            {
                throw Error.ArgumentNull("entryWrapper");
            }

            foreach (ODataNavigationLinkWithItems navigationLink in entryWrapper.NavigationLinks)
            {
                ApplyNavigationProperty(entityResource, navigationLink, entityType, readContext);
            }
        }
        public void ReadEntry_ThrowsSerializationException_TypeCannotBeDeserialized()
        {
            Mock <ODataDeserializerProvider> deserializerProvider = new Mock <ODataDeserializerProvider>();

            deserializerProvider.Setup(d => d.GetEdmTypeDeserializer(It.IsAny <IEdmTypeReference>())).Returns <ODataEdmTypeDeserializer>(null);
            var deserializer = new ODataEntityDeserializer(deserializerProvider.Object);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry {
                TypeName = _supplierEdmType.FullName()
            });

            Assert.Throws <SerializationException>(
                () => deserializer.ReadEntry(entry, _productEdmType, _readContext),
                "'ODataDemo.Supplier' cannot be deserialized using the ODataMediaTypeFormatter.");
        }
        public void ReadInline_Calls_ReadEntry()
        {
            // Arrange
            var deserializer = new Mock <ODataEntityDeserializer>(_deserializerProvider);
            ODataEntryWithNavigationLinks entry       = new ODataEntryWithNavigationLinks(new ODataEntry());
            ODataDeserializerContext      readContext = new ODataDeserializerContext();

            deserializer.CallBase = true;
            deserializer.Setup(d => d.ReadEntry(entry, _productEdmType, readContext)).Returns(42).Verifiable();

            // Act
            var result = deserializer.Object.ReadInline(entry, _productEdmType, readContext);

            // Assert
            deserializer.Verify();
            Assert.Equal(42, result);
        }
        public void ReadEntry_ThrowsODataException_CannotInstantiateAbstractEntityType()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            builder.EntityType <BaseType>().Abstract();
            IEdmModel model        = builder.GetEdmModel();
            var       deserializer = new ODataEntityDeserializer(_deserializerProvider);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry {
                TypeName = "System.Web.OData.Formatter.Deserialization.BaseType"
            });

            Assert.Throws <ODataException>(
                () => deserializer.ReadEntry(entry, _productEdmType, new ODataDeserializerContext {
                Model = model
            }),
                "An instance of the abstract entity type 'System.Web.OData.Formatter.Deserialization.BaseType' was found. Abstract entity types cannot be instantiated.");
        }
Esempio n. 12
0
        /// <summary>
        /// Deserializes the navigation property from <paramref name="navigationLinkWrapper"/> into <paramref name="entityResource"/>.
        /// </summary>
        /// <param name="entityResource">The object into which the navigation property should be read.</param>
        /// <param name="navigationLinkWrapper">The navigation link.</param>
        /// <param name="entityType">The entity type of the entity resource.</param>
        /// <param name="readContext">The deserializer context.</param>
        public virtual void ApplyNavigationProperty(object entityResource, ODataNavigationLinkWithItems navigationLinkWrapper,
                                                    IEdmEntityTypeReference entityType, ODataDeserializerContext readContext)
        {
            if (navigationLinkWrapper == null)
            {
                throw Error.ArgumentNull("navigationLinkWrapper");
            }

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

            IEdmNavigationProperty navigationProperty = entityType.FindProperty(navigationLinkWrapper.NavigationLink.Name) as IEdmNavigationProperty;

            if (navigationProperty == null)
            {
                throw new ODataException(
                          Error.Format(SRResources.NavigationPropertyNotfound, navigationLinkWrapper.NavigationLink.Name, entityType.FullName()));
            }

            foreach (ODataItemBase childItem in navigationLinkWrapper.NestedItems)
            {
                ODataEntityReferenceLinkBase entityReferenceLink = childItem as ODataEntityReferenceLinkBase;
                if (entityReferenceLink != null)
                {
                    // ignore links.
                    continue;
                }

                ODataFeedWithEntries feed = childItem as ODataFeedWithEntries;
                if (feed != null)
                {
                    ApplyFeedInNavigationProperty(navigationProperty, entityResource, feed, readContext);
                    continue;
                }

                // It must be entry by now.
                ODataEntryWithNavigationLinks entry = (ODataEntryWithNavigationLinks)childItem;
                if (entry != null)
                {
                    ApplyEntryInNavigationProperty(navigationProperty, entityResource, entry, readContext);
                }
            }
        }
        public void ReadEntry_Calls_ApplyNaviagationProperties()
        {
            // Arrange
            Mock <ODataEntityDeserializer> deserializer = new Mock <ODataEntityDeserializer>(_deserializerProvider);
            ODataEntryWithNavigationLinks  entry        = new ODataEntryWithNavigationLinks(new ODataEntry {
                Properties = Enumerable.Empty <ODataProperty>()
            });

            deserializer.CallBase = true;
            deserializer.Setup(d => d.CreateEntityResource(_productEdmType, _readContext)).Returns(42);
            deserializer.Setup(d => d.ApplyNavigationProperties(42, entry, _productEdmType, _readContext)).Verifiable();

            // Act
            deserializer.Object.ReadEntry(entry, _productEdmType, _readContext);

            // Assert
            deserializer.Verify();
        }
        public void ReadEntry_CanReadDatTimeRelatedProperties()
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            builder.EntityType <MyCustomer>().Namespace = "NS";
            IEdmModel model = builder.GetEdmModel();

            IEdmEntityTypeReference vipCustomerTypeReference = model.GetEdmTypeReference(typeof(MyCustomer)).AsEntity();

            var deserializerProvider = new DefaultODataDeserializerProvider();
            var deserializer         = new ODataEntityDeserializer(deserializerProvider);

            ODataEntry odataEntry = new ODataEntry
            {
                Properties = new[]
                {
                    new ODataProperty {
                        Name = "Id", Value = 121
                    },
                    new ODataProperty {
                        Name = "Birthday", Value = new Date(2015, 12, 12)
                    },
                    new ODataProperty {
                        Name = "ReleaseTime", Value = new TimeOfDay(1, 2, 3, 4)
                    },
                },
                TypeName = "NS.MyCustomer"
            };

            ODataDeserializerContext readContext = new ODataDeserializerContext {
                Model = model
            };
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(odataEntry);

            // Act
            var customer = deserializer.ReadEntry(entry, vipCustomerTypeReference, readContext) as MyCustomer;

            // Assert
            Assert.NotNull(customer);
            Assert.Equal(121, customer.Id);
            Assert.Equal(new DateTime(2015, 12, 12), customer.Birthday);
            Assert.Equal(new TimeSpan(0, 1, 2, 3, 4), customer.ReleaseTime);
        }
Esempio n. 15
0
        /// <inheritdoc />
        public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)
        {
            if (messageReader == null)
            {
                throw Error.ArgumentNull("messageReader");
            }

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

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

            IEdmNavigationSource navigationSource = readContext.Path.NavigationSource;

            if (navigationSource == null)
            {
                throw new SerializationException(SRResources.NavigationSourceMissingDuringDeserialization);
            }

            IEdmTypeReference edmType = readContext.GetEdmType(type);

            Contract.Assert(edmType != null);

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

            IEdmEntityTypeReference entityType = edmType.AsEntity();

            ODataReader odataReader = messageReader.CreateODataEntryReader(navigationSource, entityType.EntityDefinition());
            ODataEntryWithNavigationLinks topLevelEntry = ReadEntryOrFeed(odataReader) as ODataEntryWithNavigationLinks;

            Contract.Assert(topLevelEntry != null);

            return(ReadInline(topLevelEntry, entityType, readContext));
        }
        public void ApplyStructuralProperties_Calls_ApplyStructuralPropertyOnEachPropertyInEntry()
        {
            // Arrange
            var deserializer = new Mock <ODataEntityDeserializer>(_deserializerProvider);

            ODataProperty[] properties          = new[] { new ODataProperty(), new ODataProperty() };
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry {
                Properties = properties
            });

            deserializer.CallBase = true;
            deserializer.Setup(d => d.ApplyStructuralProperty(42, properties[0], _productEdmType, _readContext)).Verifiable();
            deserializer.Setup(d => d.ApplyStructuralProperty(42, properties[1], _productEdmType, _readContext)).Verifiable();

            // Act
            deserializer.Object.ApplyStructuralProperties(42, entry, _productEdmType, _readContext);

            // Assert
            deserializer.Verify();
        }
        public void ApplyNavigationProperties_Calls_ApplyNavigationPropertyForEachNavigationLink()
        {
            // Arrange
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry());

            entry.NavigationLinks.Add(new ODataNavigationLinkWithItems(new ODataNavigationLink()));
            entry.NavigationLinks.Add(new ODataNavigationLinkWithItems(new ODataNavigationLink()));

            Mock <ODataEntityDeserializer> deserializer = new Mock <ODataEntityDeserializer>(_deserializerProvider);

            deserializer.CallBase = true;
            deserializer.Setup(d => d.ApplyNavigationProperty(42, entry.NavigationLinks[0], _productEdmType, _readContext)).Verifiable();
            deserializer.Setup(d => d.ApplyNavigationProperty(42, entry.NavigationLinks[1], _productEdmType, _readContext)).Verifiable();

            // Act
            deserializer.Object.ApplyNavigationProperties(42, entry, _productEdmType, _readContext);

            // Assert
            deserializer.Verify();
        }
        public void ReadEntry_DispatchesToRightDeserializer_IfEntityTypeNameIsDifferent()
        {
            // Arrange
            Mock <ODataEdmTypeDeserializer>  supplierDeserializer = new Mock <ODataEdmTypeDeserializer>(ODataPayloadKind.Entry);
            Mock <ODataDeserializerProvider> deserializerProvider = new Mock <ODataDeserializerProvider>();
            var deserializer = new ODataEntityDeserializer(deserializerProvider.Object);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry {
                TypeName = _supplierEdmType.FullName()
            });

            deserializerProvider.Setup(d => d.GetEdmTypeDeserializer(It.IsAny <IEdmTypeReference>())).Returns(supplierDeserializer.Object);
            supplierDeserializer
            .Setup(d => d.ReadInline(entry, It.Is <IEdmTypeReference>(e => _supplierEdmType.Definition == e.Definition), _readContext))
            .Returns(42).Verifiable();

            // Act
            object result = deserializer.ReadEntry(entry, _productEdmType, _readContext);

            // Assert
            supplierDeserializer.Verify();
            Assert.Equal(42, result);
        }
Esempio n. 19
0
        private void ApplyEntryInNavigationProperty(IEdmNavigationProperty navigationProperty, object entityResource,
                                                    ODataEntryWithNavigationLinks entry, 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(entry, navigationProperty.Type, readContext);

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

            DeserializationHelpers.SetProperty(entityResource, propertyName, value);
        }
        public void ReadEntry_CanReadDynamicPropertiesForOpenEntityType()
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntityType<SimpleOpenCustomer>();
            builder.EnumType<SimpleEnum>();
            IEdmModel model = builder.GetEdmModel();

            IEdmEntityTypeReference customerTypeReference = model.GetEdmTypeReference(typeof(SimpleOpenCustomer)).AsEntity();

            var deserializerProvider = new DefaultODataDeserializerProvider();
            var deserializer = new ODataEntityDeserializer(deserializerProvider);

            ODataEnumValue enumValue = new ODataEnumValue("Third", typeof(SimpleEnum).FullName);

            ODataComplexValue[] complexValues =
            {
                new ODataComplexValue
                {
                    TypeName = typeof(SimpleOpenAddress).FullName,
                    Properties = new[]
                    {
                        // declared properties
                        new ODataProperty { Name = "Street", Value = "Street 1" },
                        new ODataProperty { Name = "City", Value = "City 1" },

                        // dynamic properties
                        new ODataProperty
                        {
                            Name = "DateTimeProperty",
                            Value = new DateTimeOffset(new DateTime(2014, 5, 6))
                        }
                    }
                },
                new ODataComplexValue
                {
                    TypeName = typeof(SimpleOpenAddress).FullName,
                    Properties = new[]
                    {
                        // declared properties
                        new ODataProperty { Name = "Street", Value = "Street 2" },
                        new ODataProperty { Name = "City", Value = "City 2" },

                        // dynamic properties
                        new ODataProperty
                        {
                            Name = "ArrayProperty",
                            Value = new ODataCollectionValue { TypeName = "Collection(Edm.Int32)", Items = new[] {1, 2, 3, 4} }
                        }
                    }
                }
            };

            ODataCollectionValue collectionValue = new ODataCollectionValue
            {
                TypeName = "Collection(" + typeof(SimpleOpenAddress).FullName + ")",
                Items = complexValues
            };

            ODataEntry odataEntry = new ODataEntry
            {
                Properties = new[]
                {
                    // declared properties
                    new ODataProperty { Name = "CustomerId", Value = 991 },
                    new ODataProperty { Name = "Name", Value = "Name #991" },

                    // dynamic properties
                    new ODataProperty { Name = "GuidProperty", Value = new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA") },
                    new ODataProperty { Name = "EnumValue", Value = enumValue },
                    new ODataProperty { Name = "CollectionProperty", Value = collectionValue }
                },
                TypeName = typeof(SimpleOpenCustomer).FullName
            };

            ODataDeserializerContext readContext = new ODataDeserializerContext()
            {
                Model = model
            };

            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(odataEntry);

            // Act
            SimpleOpenCustomer customer = deserializer.ReadEntry(entry, customerTypeReference, readContext)
                as SimpleOpenCustomer;

            // Assert
            Assert.NotNull(customer);

            // Verify the declared properties
            Assert.Equal(991, customer.CustomerId);
            Assert.Equal("Name #991", customer.Name);

            // Verify the dynamic properties
            Assert.NotNull(customer.CustomerProperties);
            Assert.Equal(3, customer.CustomerProperties.Count());
            Assert.Equal(new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"), customer.CustomerProperties["GuidProperty"]);
            Assert.Equal(SimpleEnum.Third, customer.CustomerProperties["EnumValue"]);

            // Verify the dynamic collection property
            var collectionValues = Assert.IsType<List<SimpleOpenAddress>>(customer.CustomerProperties["CollectionProperty"]);
            Assert.NotNull(collectionValues);
            Assert.Equal(2, collectionValues.Count());

            Assert.Equal(new DateTimeOffset(new DateTime(2014, 5, 6)), collectionValues[0].Properties["DateTimeProperty"]);
            Assert.Equal(new List<int> { 1, 2, 3, 4 }, collectionValues[1].Properties["ArrayProperty"]);
        }
        public void ReadEntry_Calls_ApplyNaviagationProperties()
        {
            // Arrange
            Mock<ODataEntityDeserializer> deserializer = new Mock<ODataEntityDeserializer>(_deserializerProvider);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry { Properties = Enumerable.Empty<ODataProperty>() });
            deserializer.CallBase = true;
            deserializer.Setup(d => d.CreateEntityResource(_productEdmType, _readContext)).Returns(42);
            deserializer.Setup(d => d.ApplyNavigationProperties(42, entry, _productEdmType, _readContext)).Verifiable();

            // Act
            deserializer.Object.ReadEntry(entry, _productEdmType, _readContext);

            // Assert
            deserializer.Verify();
        }
 public void ReadEntry_ThrowsArgumentNull_ReadContext()
 {
     var deserializer = new ODataEntityDeserializer(_deserializerProvider);
     ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry());
     Assert.ThrowsArgumentNull(
         () => deserializer.ReadEntry(entry, entityType: _productEdmType, readContext: null),
         "readContext");
 }
Esempio n. 23
0
        /// <summary>
        /// Reads an ODataFeed or an ODataItem from the reader.
        /// </summary>
        /// <param name="reader">The OData reader to read from.</param>
        /// <returns>The read feed or entry.</returns>
        public static ODataItemBase ReadEntryOrFeed(ODataReader reader)
        {
            if (reader == null)
            {
                throw Error.ArgumentNull("odataReader");
            }

            ODataItemBase         topLevelItem = null;
            Stack <ODataItemBase> itemsStack   = new Stack <ODataItemBase>();

            while (reader.Read())
            {
                switch (reader.State)
                {
                case ODataReaderState.EntryStart:
                    ODataEntry entry = (ODataEntry)reader.Item;
                    ODataEntryWithNavigationLinks entryWrapper = null;
                    if (entry != null)
                    {
                        entryWrapper = new ODataEntryWithNavigationLinks(entry);
                    }

                    if (itemsStack.Count == 0)
                    {
                        Contract.Assert(entry != null, "The top-level entry can never be null.");
                        topLevelItem = entryWrapper;
                    }
                    else
                    {
                        ODataItemBase        parentItem = itemsStack.Peek();
                        ODataFeedWithEntries parentFeed = parentItem as ODataFeedWithEntries;
                        if (parentFeed != null)
                        {
                            parentFeed.Entries.Add(entryWrapper);
                        }
                        else
                        {
                            ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)parentItem;
                            Contract.Assert(parentNavigationLink.NavigationLink.IsCollection == false, "Only singleton navigation properties can contain entry as their child.");
                            Contract.Assert(parentNavigationLink.NestedItems.Count == 0, "Each navigation property can contain only one entry as its direct child.");
                            parentNavigationLink.NestedItems.Add(entryWrapper);
                        }
                    }
                    itemsStack.Push(entryWrapper);
                    break;

                case ODataReaderState.EntryEnd:
                    Contract.Assert(itemsStack.Count > 0 && (reader.Item == null || itemsStack.Peek().Item == reader.Item), "The entry which is ending should be on the top of the items stack.");
                    itemsStack.Pop();
                    break;

                case ODataReaderState.NavigationLinkStart:
                    ODataNavigationLink navigationLink = (ODataNavigationLink)reader.Item;
                    Contract.Assert(navigationLink != null, "Navigation link should never be null.");

                    ODataNavigationLinkWithItems navigationLinkWrapper = new ODataNavigationLinkWithItems(navigationLink);
                    Contract.Assert(itemsStack.Count > 0, "Navigation link can't appear as top-level item.");
                    {
                        ODataEntryWithNavigationLinks parentEntry = (ODataEntryWithNavigationLinks)itemsStack.Peek();
                        parentEntry.NavigationLinks.Add(navigationLinkWrapper);
                    }

                    itemsStack.Push(navigationLinkWrapper);
                    break;

                case ODataReaderState.NavigationLinkEnd:
                    Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The navigation link which is ending should be on the top of the items stack.");
                    itemsStack.Pop();
                    break;

                case ODataReaderState.FeedStart:
                    ODataFeed feed = (ODataFeed)reader.Item;
                    Contract.Assert(feed != null, "Feed should never be null.");

                    ODataFeedWithEntries feedWrapper = new ODataFeedWithEntries(feed);
                    if (itemsStack.Count > 0)
                    {
                        ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)itemsStack.Peek();
                        Contract.Assert(parentNavigationLink != null, "this has to be an inner feed. inner feeds always have a navigation link.");
                        Contract.Assert(parentNavigationLink.NavigationLink.IsCollection == true, "Only collection navigation properties can contain feed as their child.");
                        parentNavigationLink.NestedItems.Add(feedWrapper);
                    }
                    else
                    {
                        topLevelItem = feedWrapper;
                    }

                    itemsStack.Push(feedWrapper);
                    break;

                case ODataReaderState.FeedEnd:
                    Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The feed which is ending should be on the top of the items stack.");
                    itemsStack.Pop();
                    break;

                case ODataReaderState.EntityReferenceLink:
                    ODataEntityReferenceLink entityReferenceLink = (ODataEntityReferenceLink)reader.Item;
                    Contract.Assert(entityReferenceLink != null, "Entity reference link should never be null.");
                    ODataEntityReferenceLinkBase entityReferenceLinkWrapper = new ODataEntityReferenceLinkBase(entityReferenceLink);

                    Contract.Assert(itemsStack.Count > 0, "Entity reference link should never be reported as top-level item.");
                    {
                        ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)itemsStack.Peek();
                        parentNavigationLink.NestedItems.Add(entityReferenceLinkWrapper);
                    }

                    break;

                default:
                    Contract.Assert(false, "We should never get here, it means the ODataReader reported a wrong state.");
                    break;
                }
            }

            Contract.Assert(reader.State == ODataReaderState.Completed, "We should have consumed all of the input by now.");
            Contract.Assert(topLevelItem != null, "A top level entry or feed should have been read by now.");
            return(topLevelItem);
        }
        public void ReadEntry_ThrowsODataException_EntityTypeNotInModel()
        {
            var deserializer = new ODataEntityDeserializer(_deserializerProvider);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry { TypeName = "MissingType" });

            Assert.Throws<ODataException>(
                () => deserializer.ReadEntry(entry, _productEdmType, _readContext),
                "Cannot find the entity type 'MissingType' in the model.");
        }
        public void ReadEntry_CanReadDynamicPropertiesForInheritanceOpenEntityType()
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            builder.EntityType <SimpleOpenCustomer>();
            builder.EnumType <SimpleEnum>();
            IEdmModel model = builder.GetEdmModel();

            IEdmEntityTypeReference vipCustomerTypeReference = model.GetEdmTypeReference(typeof(SimpleVipCustomer)).AsEntity();

            var deserializerProvider = new DefaultODataDeserializerProvider();
            var deserializer         = new ODataEntityDeserializer(deserializerProvider);

            ODataEntry odataEntry = new ODataEntry
            {
                Properties = new[]
                {
                    // declared properties
                    new ODataProperty {
                        Name = "CustomerId", Value = 121
                    },
                    new ODataProperty {
                        Name = "Name", Value = "VipName #121"
                    },
                    new ODataProperty {
                        Name = "VipNum", Value = "Vip Num 001"
                    },

                    // dynamic properties
                    new ODataProperty {
                        Name = "GuidProperty", Value = new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA")
                    },
                },
                TypeName = typeof(SimpleVipCustomer).FullName
            };

            ODataDeserializerContext readContext = new ODataDeserializerContext()
            {
                Model = model
            };

            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(odataEntry);

            // Act
            SimpleVipCustomer customer = deserializer.ReadEntry(entry, vipCustomerTypeReference, readContext)
                                         as SimpleVipCustomer;

            // Assert
            Assert.NotNull(customer);

            // Verify the declared properties
            Assert.Equal(121, customer.CustomerId);
            Assert.Equal("VipName #121", customer.Name);
            Assert.Equal("Vip Num 001", customer.VipNum);

            // Verify the dynamic properties
            Assert.NotNull(customer.CustomerProperties);
            Assert.Equal(1, customer.CustomerProperties.Count());
            Assert.Equal(new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"), customer.CustomerProperties["GuidProperty"]);
        }
        /// <summary>
        /// Deserializes the structural properties from <paramref name="entryWrapper"/> into <paramref name="entityResource"/>.
        /// </summary>
        /// <param name="entityResource">The object into which the structural properties should be read.</param>
        /// <param name="entryWrapper">The entry object containing the structural properties.</param>
        /// <param name="entityType">The entity type of the entity resource.</param>
        /// <param name="readContext">The deserializer context.</param>
        public virtual void ApplyStructuralProperties(object entityResource, ODataEntryWithNavigationLinks entryWrapper,
            IEdmEntityTypeReference entityType, ODataDeserializerContext readContext)
        {
            if (entryWrapper == null)
            {
                throw Error.ArgumentNull("entryWrapper");
            }

            foreach (ODataProperty property in entryWrapper.Entry.Properties)
            {
                ApplyStructuralProperty(entityResource, property, entityType, readContext);
            }
        }
        public void ReadEntry_ThrowsSerializationException_TypeCannotBeDeserialized()
        {
            Mock<ODataDeserializerProvider> deserializerProvider = new Mock<ODataDeserializerProvider>();
            deserializerProvider.Setup(d => d.GetEdmTypeDeserializer(It.IsAny<IEdmTypeReference>())).Returns<ODataEdmTypeDeserializer>(null);
            var deserializer = new ODataEntityDeserializer(deserializerProvider.Object);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry { TypeName = _supplierEdmType.FullName() });

            Assert.Throws<SerializationException>(
                () => deserializer.ReadEntry(entry, _productEdmType, _readContext),
                "'ODataDemo.Supplier' cannot be deserialized using the ODataMediaTypeFormatter.");
        }
        /// <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;
            }
        }
        /// <summary>
        /// Deserializes the navigation properties from <paramref name="entryWrapper"/> into <paramref name="entityResource"/>.
        /// </summary>
        /// <param name="entityResource">The object into which the navigation properties should be read.</param>
        /// <param name="entryWrapper">The entry object containing the navigation properties.</param>
        /// <param name="entityType">The entity type of the entity resource.</param>
        /// <param name="readContext">The deserializer context.</param>
        public virtual void ApplyNavigationProperties(object entityResource, ODataEntryWithNavigationLinks entryWrapper,
            IEdmEntityTypeReference entityType, ODataDeserializerContext readContext)
        {
            if (entryWrapper == null)
            {
                throw Error.ArgumentNull("entryWrapper");
            }

            foreach (ODataNavigationLinkWithItems navigationLink in entryWrapper.NavigationLinks)
            {
                ApplyNavigationProperty(entityResource, navigationLink, entityType, readContext);
            }
        }
        public void ApplyNavigationProperties_Calls_ApplyNavigationPropertyForEachNavigationLink()
        {
            // Arrange
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry());
            entry.NavigationLinks.Add(new ODataNavigationLinkWithItems(new ODataNavigationLink()));
            entry.NavigationLinks.Add(new ODataNavigationLinkWithItems(new ODataNavigationLink()));

            Mock<ODataEntityDeserializer> deserializer = new Mock<ODataEntityDeserializer>(_deserializerProvider);
            deserializer.CallBase = true;
            deserializer.Setup(d => d.ApplyNavigationProperty(42, entry.NavigationLinks[0], _productEdmType, _readContext)).Verifiable();
            deserializer.Setup(d => d.ApplyNavigationProperty(42, entry.NavigationLinks[1], _productEdmType, _readContext)).Verifiable();

            // Act
            deserializer.Object.ApplyNavigationProperties(42, entry, _productEdmType, _readContext);

            // Assert
            deserializer.Verify();
        }
        public void ReadInline_Calls_ReadEntry()
        {
            // Arrange
            var deserializer = new Mock<ODataEntityDeserializer>(_deserializerProvider);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry());
            ODataDeserializerContext readContext = new ODataDeserializerContext();

            deserializer.CallBase = true;
            deserializer.Setup(d => d.ReadEntry(entry, _productEdmType, readContext)).Returns(42).Verifiable();

            // Act
            var result = deserializer.Object.ReadInline(entry, _productEdmType, readContext);

            // Assert
            deserializer.Verify();
            Assert.Equal(42, result);
        }
Esempio n. 32
0
 private void ApplyEntityProperties(object entityResource, ODataEntryWithNavigationLinks entryWrapper,
                                    IEdmEntityTypeReference entityType, ODataDeserializerContext readContext)
 {
     ApplyStructuralProperties(entityResource, entryWrapper, entityType, readContext);
     ApplyNavigationProperties(entityResource, entryWrapper, entityType, readContext);
 }
        public void ReadEntry_SetsExpectedAndActualEdmType_OnCreatedEdmObject_TypelessMode()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            IEdmEntityTypeReference customerType = EdmLibHelpers.ToEdmTypeReference(model.Customer, isNullable: false).AsEntity();
            ODataDeserializerContext readContext = new ODataDeserializerContext { Model = model.Model, ResourceType = typeof(IEdmObject) };
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry
            {
                TypeName = model.SpecialCustomer.FullName(),
                Properties = new ODataProperty[0]
            });

            ODataEntityDeserializer deserializer = new ODataEntityDeserializer(_deserializerProvider);

            // Act
            var result = deserializer.ReadEntry(entry, customerType, readContext);

            // Assert
            EdmEntityObject resource = Assert.IsType<EdmEntityObject>(result);
            Assert.Equal(model.SpecialCustomer, resource.ActualEdmType);
            Assert.Equal(model.Customer, resource.ExpectedEdmType);
        }
        /// <summary>
        /// Reads an ODataFeed or an ODataItem from the reader.
        /// </summary>
        /// <param name="reader">The OData reader to read from.</param>
        /// <returns>The read feed or entry.</returns>
        public static ODataItemBase ReadEntryOrFeed(ODataReader reader)
        {
            if (reader == null)
            {
                throw Error.ArgumentNull("odataReader");
            }

            ODataItemBase topLevelItem = null;
            Stack<ODataItemBase> itemsStack = new Stack<ODataItemBase>();

            while (reader.Read())
            {
                switch (reader.State)
                {
                    case ODataReaderState.EntryStart:
                        ODataEntry entry = (ODataEntry)reader.Item;
                        ODataEntryWithNavigationLinks entryWrapper = null;
                        if (entry != null)
                        {
                            entryWrapper = new ODataEntryWithNavigationLinks(entry);
                        }

                        if (itemsStack.Count == 0)
                        {
                            Contract.Assert(entry != null, "The top-level entry can never be null.");
                            topLevelItem = entryWrapper;
                        }
                        else
                        {
                            ODataItemBase parentItem = itemsStack.Peek();
                            ODataFeedWithEntries parentFeed = parentItem as ODataFeedWithEntries;
                            if (parentFeed != null)
                            {
                                parentFeed.Entries.Add(entryWrapper);
                            }
                            else
                            {
                                ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)parentItem;
                                Contract.Assert(parentNavigationLink.NavigationLink.IsCollection == false, "Only singleton navigation properties can contain entry as their child.");
                                Contract.Assert(parentNavigationLink.NestedItems.Count == 0, "Each navigation property can contain only one entry as its direct child.");
                                parentNavigationLink.NestedItems.Add(entryWrapper);
                            }
                        }
                        itemsStack.Push(entryWrapper);
                        break;

                    case ODataReaderState.EntryEnd:
                        Contract.Assert(itemsStack.Count > 0 && (reader.Item == null || itemsStack.Peek().Item == reader.Item), "The entry which is ending should be on the top of the items stack.");
                        itemsStack.Pop();
                        break;

                    case ODataReaderState.NavigationLinkStart:
                        ODataNavigationLink navigationLink = (ODataNavigationLink)reader.Item;
                        Contract.Assert(navigationLink != null, "Navigation link should never be null.");

                        ODataNavigationLinkWithItems navigationLinkWrapper = new ODataNavigationLinkWithItems(navigationLink);
                        Contract.Assert(itemsStack.Count > 0, "Navigation link can't appear as top-level item.");
                        {
                            ODataEntryWithNavigationLinks parentEntry = (ODataEntryWithNavigationLinks)itemsStack.Peek();
                            parentEntry.NavigationLinks.Add(navigationLinkWrapper);
                        }

                        itemsStack.Push(navigationLinkWrapper);
                        break;

                    case ODataReaderState.NavigationLinkEnd:
                        Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The navigation link which is ending should be on the top of the items stack.");
                        itemsStack.Pop();
                        break;

                    case ODataReaderState.FeedStart:
                        ODataFeed feed = (ODataFeed)reader.Item;
                        Contract.Assert(feed != null, "Feed should never be null.");

                        ODataFeedWithEntries feedWrapper = new ODataFeedWithEntries(feed);
                        if (itemsStack.Count > 0)
                        {
                            ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)itemsStack.Peek();
                            Contract.Assert(parentNavigationLink != null, "this has to be an inner feed. inner feeds always have a navigation link.");
                            Contract.Assert(parentNavigationLink.NavigationLink.IsCollection == true, "Only collection navigation properties can contain feed as their child.");
                            parentNavigationLink.NestedItems.Add(feedWrapper);
                        }
                        else
                        {
                            topLevelItem = feedWrapper;
                        }

                        itemsStack.Push(feedWrapper);
                        break;

                    case ODataReaderState.FeedEnd:
                        Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The feed which is ending should be on the top of the items stack.");
                        itemsStack.Pop();
                        break;

                    case ODataReaderState.EntityReferenceLink:
                        ODataEntityReferenceLink entityReferenceLink = (ODataEntityReferenceLink)reader.Item;
                        Contract.Assert(entityReferenceLink != null, "Entity reference link should never be null.");
                        ODataEntityReferenceLinkBase entityReferenceLinkWrapper = new ODataEntityReferenceLinkBase(entityReferenceLink);

                        Contract.Assert(itemsStack.Count > 0, "Entity reference link should never be reported as top-level item.");
                        {
                            ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)itemsStack.Peek();
                            parentNavigationLink.NestedItems.Add(entityReferenceLinkWrapper);
                        }

                        break;

                    default:
                        Contract.Assert(false, "We should never get here, it means the ODataReader reported a wrong state.");
                        break;
                }
            }

            Contract.Assert(reader.State == ODataReaderState.Completed, "We should have consumed all of the input by now.");
            Contract.Assert(topLevelItem != null, "A top level entry or feed should have been read by now.");
            return topLevelItem;
        }
        public void ReadEntry_DispatchesToRightDeserializer_IfEntityTypeNameIsDifferent()
        {
            // Arrange
            Mock<ODataEdmTypeDeserializer> supplierDeserializer = new Mock<ODataEdmTypeDeserializer>(ODataPayloadKind.Entry);
            Mock<ODataDeserializerProvider> deserializerProvider = new Mock<ODataDeserializerProvider>();
            var deserializer = new ODataEntityDeserializer(deserializerProvider.Object);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry { TypeName = _supplierEdmType.FullName() });

            deserializerProvider.Setup(d => d.GetEdmTypeDeserializer(It.IsAny<IEdmTypeReference>())).Returns(supplierDeserializer.Object);
            supplierDeserializer
                .Setup(d => d.ReadInline(entry, It.Is<IEdmTypeReference>(e => _supplierEdmType.Definition == e.Definition), _readContext))
                .Returns(42).Verifiable();

            // Act
            object result = deserializer.ReadEntry(entry, _productEdmType, _readContext);

            // Assert
            supplierDeserializer.Verify();
            Assert.Equal(42, result);
        }
 private void ApplyEntityProperties(object entityResource, ODataEntryWithNavigationLinks entryWrapper,
     IEdmEntityTypeReference entityType, ODataDeserializerContext readContext)
 {
     ApplyStructuralProperties(entityResource, entryWrapper, entityType, readContext);
     ApplyNavigationProperties(entityResource, entryWrapper, entityType, readContext);
 }
        public void ReadEntry_ThrowsODataException_CannotInstantiateAbstractEntityType()
        {
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntityType<BaseType>().Abstract();
            IEdmModel model = builder.GetEdmModel();
            var deserializer = new ODataEntityDeserializer(_deserializerProvider);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry { TypeName = "System.Web.OData.Formatter.Deserialization.BaseType" });

            Assert.Throws<ODataException>(
                () => deserializer.ReadEntry(entry, _productEdmType, new ODataDeserializerContext { Model = model }),
                "An instance of the abstract entity type 'System.Web.OData.Formatter.Deserialization.BaseType' was found. Abstract entity types cannot be instantiated.");
        }
        private void ApplyEntryInNavigationProperty(IEdmNavigationProperty navigationProperty, object entityResource,
            ODataEntryWithNavigationLinks entry, 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(entry, navigationProperty.Type, readContext);

            string propertyName = EdmLibHelpers.GetClrPropertyName(navigationProperty, readContext.Model);
            DeserializationHelpers.SetProperty(entityResource, propertyName, value);
        }
        public void ReadEntry_CanReadDynamicPropertiesForOpenEntityType()
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

            builder.EntityType <SimpleOpenCustomer>();
            builder.EnumType <SimpleEnum>();
            IEdmModel model = builder.GetEdmModel();

            IEdmEntityTypeReference customerTypeReference = model.GetEdmTypeReference(typeof(SimpleOpenCustomer)).AsEntity();

            var deserializerProvider = new DefaultODataDeserializerProvider();
            var deserializer         = new ODataEntityDeserializer(deserializerProvider);

            ODataEnumValue enumValue = new ODataEnumValue("Third", typeof(SimpleEnum).FullName);

            ODataComplexValue[] complexValues =
            {
                new ODataComplexValue
                {
                    TypeName   = typeof(SimpleOpenAddress).FullName,
                    Properties = new[]
                    {
                        // declared properties
                        new ODataProperty {
                            Name = "Street", Value = "Street 1"
                        },
                        new ODataProperty {
                            Name = "City", Value = "City 1"
                        },

                        // dynamic properties
                        new ODataProperty
                        {
                            Name  = "DateTimeProperty",
                            Value = new DateTimeOffset(new DateTime(2014, 5, 6))
                        }
                    }
                },
                new ODataComplexValue
                {
                    TypeName   = typeof(SimpleOpenAddress).FullName,
                    Properties = new[]
                    {
                        // declared properties
                        new ODataProperty {
                            Name = "Street", Value = "Street 2"
                        },
                        new ODataProperty {
                            Name = "City", Value = "City 2"
                        },

                        // dynamic properties
                        new ODataProperty
                        {
                            Name  = "ArrayProperty",
                            Value = new ODataCollectionValue{
                                TypeName = "Collection(Edm.Int32)", Items = new[]{                                         1, 2, 3, 4 }
                            }
                        }
                    }
                }
            };

            ODataCollectionValue collectionValue = new ODataCollectionValue
            {
                TypeName = "Collection(" + typeof(SimpleOpenAddress).FullName + ")",
                Items    = complexValues
            };

            ODataEntry odataEntry = new ODataEntry
            {
                Properties = new[]
                {
                    // declared properties
                    new ODataProperty {
                        Name = "CustomerId", Value = 991
                    },
                    new ODataProperty {
                        Name = "Name", Value = "Name #991"
                    },

                    // dynamic properties
                    new ODataProperty {
                        Name = "GuidProperty", Value = new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA")
                    },
                    new ODataProperty {
                        Name = "EnumValue", Value = enumValue
                    },
                    new ODataProperty {
                        Name = "CollectionProperty", Value = collectionValue
                    }
                },
                TypeName = typeof(SimpleOpenCustomer).FullName
            };

            ODataDeserializerContext readContext = new ODataDeserializerContext()
            {
                Model = model
            };

            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(odataEntry);

            // Act
            SimpleOpenCustomer customer = deserializer.ReadEntry(entry, customerTypeReference, readContext)
                                          as SimpleOpenCustomer;

            // Assert
            Assert.NotNull(customer);

            // Verify the declared properties
            Assert.Equal(991, customer.CustomerId);
            Assert.Equal("Name #991", customer.Name);

            // Verify the dynamic properties
            Assert.NotNull(customer.CustomerProperties);
            Assert.Equal(3, customer.CustomerProperties.Count());
            Assert.Equal(new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"), customer.CustomerProperties["GuidProperty"]);
            Assert.Equal(SimpleEnum.Third, customer.CustomerProperties["EnumValue"]);

            // Verify the dynamic collection property
            var collectionValues = Assert.IsType <List <SimpleOpenAddress> >(customer.CustomerProperties["CollectionProperty"]);

            Assert.NotNull(collectionValues);
            Assert.Equal(2, collectionValues.Count());

            Assert.Equal(new DateTimeOffset(new DateTime(2014, 5, 6)), collectionValues[0].Properties["DateTimeProperty"]);
            Assert.Equal(new List <int> {
                1, 2, 3, 4
            }, collectionValues[1].Properties["ArrayProperty"]);
        }
        public void ReadEntry_CanReadDatTimeRelatedProperties()
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntityType<MyCustomer>().Namespace = "NS";
            IEdmModel model = builder.GetEdmModel();

            IEdmEntityTypeReference vipCustomerTypeReference = model.GetEdmTypeReference(typeof(MyCustomer)).AsEntity();

            var deserializerProvider = new DefaultODataDeserializerProvider();
            var deserializer = new ODataEntityDeserializer(deserializerProvider);

            ODataEntry odataEntry = new ODataEntry
            {
                Properties = new[]
                {
                    new ODataProperty { Name = "Id", Value = 121 },
                    new ODataProperty { Name = "Birthday", Value = new Date(2015, 12, 12) },
                    new ODataProperty { Name = "ReleaseTime", Value = new TimeOfDay(1, 2, 3, 4) },
                },
                TypeName = "NS.MyCustomer"
            };

            ODataDeserializerContext readContext = new ODataDeserializerContext { Model = model };
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(odataEntry);

            // Act
            var customer = deserializer.ReadEntry(entry, vipCustomerTypeReference, readContext) as MyCustomer;

            // Assert
            Assert.NotNull(customer);
            Assert.Equal(121, customer.Id);
            Assert.Equal(new DateTime(2015, 12, 12), customer.Birthday);
            Assert.Equal(new TimeSpan(0, 1, 2, 3, 4), customer.ReleaseTime);
        }
        public void ReadEntry_ThrowsArgument_ModelMissingFromReadContext()
        {
            var deserializer = new ODataEntityDeserializer(_deserializerProvider);
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry { TypeName = _supplierEdmType.FullName() });

            Assert.ThrowsArgument(
                () => deserializer.ReadEntry(entry, _productEdmType, new ODataDeserializerContext()),
                "readContext",
                "The EDM model is missing on the read context. The model is required on the read context to deserialize the payload.");
        }
        public void ReadEntry_CanReadDynamicPropertiesForInheritanceOpenEntityType()
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntityType<SimpleOpenCustomer>();
            builder.EnumType<SimpleEnum>();
            IEdmModel model = builder.GetEdmModel();

            IEdmEntityTypeReference vipCustomerTypeReference = model.GetEdmTypeReference(typeof(SimpleVipCustomer)).AsEntity();

            var deserializerProvider = new DefaultODataDeserializerProvider();
            var deserializer = new ODataEntityDeserializer(deserializerProvider);

            ODataEntry odataEntry = new ODataEntry
            {
                Properties = new[]
                {
                    // declared properties
                    new ODataProperty { Name = "CustomerId", Value = 121 },
                    new ODataProperty { Name = "Name", Value = "VipName #121" },
                    new ODataProperty { Name = "VipNum", Value = "Vip Num 001" },

                    // dynamic properties
                    new ODataProperty { Name = "GuidProperty", Value = new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA") },
                },
                TypeName = typeof(SimpleVipCustomer).FullName
            };

            ODataDeserializerContext readContext = new ODataDeserializerContext()
            {
                Model = model
            };

            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(odataEntry);

            // Act
            SimpleVipCustomer customer = deserializer.ReadEntry(entry, vipCustomerTypeReference, readContext)
                as SimpleVipCustomer;

            // Assert
            Assert.NotNull(customer);

            // Verify the declared properties
            Assert.Equal(121, customer.CustomerId);
            Assert.Equal("VipName #121", customer.Name);
            Assert.Equal("Vip Num 001", customer.VipNum);

            // Verify the dynamic properties
            Assert.NotNull(customer.CustomerProperties);
            Assert.Equal(1, customer.CustomerProperties.Count());
            Assert.Equal(new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"), customer.CustomerProperties["GuidProperty"]);
        }
Esempio n. 43
0
        public Object ParseAsync(HttpResponseMessage response)
        {
            using (Stream stream = response.Content.ReadAsStreamAsync().Result)
            {
                var responseMessage = new ODataResponseMessage(stream);

                var context = new ODataDeserializerContext() { Model = Model, Request = response.RequestMessage };
                using (var messageReader = new ODataMessageReader(responseMessage, _settings, Model))
                {
                    ODataResult result = GetODataResult(messageReader);
                    while (result.ODataReader.Read())
                    {
                        if (result.ODataReader.State == ODataReaderState.EntryEnd)
                        {
                            var entry = (ODataEntry)result.ODataReader.Item;
                            var entityType = (IEdmEntityType)Model.FindType(entry.TypeName);
                            var entityTypeReference = new EdmEntityTypeReference(entityType, false);
                            var navigationLinks = new ODataEntryWithNavigationLinks(entry);

                            result.AddResult(_deserializer.ReadEntry(navigationLinks, entityTypeReference, context));
                        }
                    }

                    return result.Result;
                }
            }
        }
        public void ApplyStructuralProperties_Calls_ApplyStructuralPropertyOnEachPropertyInEntry()
        {
            // Arrange
            var deserializer = new Mock<ODataEntityDeserializer>(_deserializerProvider);
            ODataProperty[] properties = new[] { new ODataProperty(), new ODataProperty() };
            ODataEntryWithNavigationLinks entry = new ODataEntryWithNavigationLinks(new ODataEntry { Properties = properties });

            deserializer.CallBase = true;
            deserializer.Setup(d => d.ApplyStructuralProperty(42, properties[0], _productEdmType, _readContext)).Verifiable();
            deserializer.Setup(d => d.ApplyStructuralProperty(42, properties[1], _productEdmType, _readContext)).Verifiable();

            // Act
            deserializer.Object.ApplyStructuralProperties(42, entry, _productEdmType, _readContext);

            // Assert
            deserializer.Verify();
        }