public void CanSerializerSingleton()
        {
            // Arrange
            const string expect = "{" +
                "\"@odata.context\":\"http://localhost/odata/$metadata#Boss\"," +
                "\"@odata.id\":\"http://localhost/odata/Boss\"," +
                "\"@odata.editLink\":\"http://localhost/odata/Boss\"," +
                "\"EmployeeId\":987,\"EmployeeName\":\"John Mountain\"}";

            IEdmModel model = GetEdmModel();
            IEdmSingleton singleton = model.EntityContainer.FindSingleton("Boss");
            HttpRequestMessage request = GetRequest(model, singleton);
            ODataSerializerContext readContext = new ODataSerializerContext()
            {
                Url = new UrlHelper(request),
                Path = request.ODataProperties().Path,
                Model = model,
                NavigationSource = singleton
            };

            ODataSerializerProvider serializerProvider = new DefaultODataSerializerProvider();
            EmployeeModel boss = new EmployeeModel {EmployeeId = 987, EmployeeName = "John Mountain"};
            MemoryStream bufferedStream = new MemoryStream();

            // Act
            ODataEntityTypeSerializer serializer = new ODataEntityTypeSerializer(serializerProvider);
            serializer.WriteObject(boss, typeof(EmployeeModel), GetODataMessageWriter(model, bufferedStream), readContext);

            // Assert
            string result = Encoding.UTF8.GetString(bufferedStream.ToArray());
            Assert.Equal(expect, result);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DefaultODataSerializerProvider"/> class.
 /// </summary>
 public DefaultODataSerializerProvider()
 {
     _feedSerializer = new ODataFeedSerializer(this);
     _collectionSerializer = new ODataCollectionSerializer(this);
     _complexTypeSerializer = new ODataComplexTypeSerializer(this);
     _entityTypeSerializer = new ODataEntityTypeSerializer(this);
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="DefaultODataSerializerProvider"/> class.
 /// </summary>
 public DefaultODataSerializerProvider()
 {
     _feedSerializer        = new ODataFeedSerializer(this);
     _collectionSerializer  = new ODataCollectionSerializer(this);
     _complexTypeSerializer = new ODataComplexTypeSerializer(this);
     _entityTypeSerializer  = new ODataEntityTypeSerializer(this);
 }
        public ODataEntityTypeSerializerTests()
        {
            _model = SerializationTestsHelpers.SimpleCustomerOrderModel();

            _model.SetAnnotationValue<ClrTypeAnnotation>(_model.FindType("Default.Customer"), new ClrTypeAnnotation(typeof(Customer)));
            _model.SetAnnotationValue<ClrTypeAnnotation>(_model.FindType("Default.Order"), new ClrTypeAnnotation(typeof(Order)));

            _customerSet = _model.FindDeclaredEntityContainer("Default.Container").FindEntitySet("Customers");
            _customer = new Customer()
            {
                FirstName = "Foo",
                LastName = "Bar",
                ID = 10,
            };

            _serializerProvider = new DefaultODataSerializerProvider();
            _customerType = _model.GetEdmTypeReference(typeof(Customer)).AsEntity();
            _serializer = new ODataEntityTypeSerializer(_serializerProvider);
            _path = new ODataPath(new EntitySetPathSegment(_customerSet));
            _writeContext = new ODataSerializerContext() { EntitySet = _customerSet, Model = _model, Path = _path };
            _entityInstanceContext = new EntityInstanceContext(_writeContext, _customerSet.ElementType.AsReference(), _customer);
        }
        public void CreateStructuralProperty_Calls_CreateODataValueOnInnerSerializer()
        {
            // Arrange
            Mock<IEdmTypeReference> propertyType = new Mock<IEdmTypeReference>();
            propertyType.Setup(t => t.Definition).Returns(new EdmEntityType("Namespace", "Name"));
            Mock<IEdmStructuralProperty> property = new Mock<IEdmStructuralProperty>();
            property.Setup(p => p.Name).Returns("PropertyName");
            Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>(MockBehavior.Strict);
            var entity = new { PropertyName = 42 };
            Mock<ODataEdmTypeSerializer> innerSerializer = new Mock<ODataEdmTypeSerializer>(ODataPayloadKind.Property);
            ODataValue propertyValue = new Mock<ODataValue>().Object;

            property.Setup(p => p.Type).Returns(propertyType.Object);
            serializerProvider.Setup(s => s.GetEdmTypeSerializer(propertyType.Object)).Returns(innerSerializer.Object);
            innerSerializer.Setup(s => s.CreateODataValue(42, propertyType.Object, _writeContext)).Returns(propertyValue).Verifiable();

            var serializer = new ODataEntityTypeSerializer(serializerProvider.Object);
            EntityInstanceContext entityInstanceContext = new EntityInstanceContext(_writeContext, _customerType, entity);

            // Act
            ODataProperty createdProperty = serializer.CreateStructuralProperty(property.Object, entityInstanceContext);

            // Assert
            innerSerializer.Verify();
            Assert.Equal("PropertyName", createdProperty.Name);
            Assert.Equal(propertyValue, createdProperty.Value);
        }
        public void CreateStructuralProperty_ThrowsSerializationException_TypeCannotBeSerialized()
        {
            // Arrange
            Mock<IEdmTypeReference> propertyType = new Mock<IEdmTypeReference>();
            propertyType.Setup(t => t.Definition).Returns(new EdmEntityType("Namespace", "Name"));
            Mock<IEdmStructuralProperty> property = new Mock<IEdmStructuralProperty>();
            Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>(MockBehavior.Strict);
            IEdmEntityObject entity = new Mock<IEdmEntityObject>().Object;
            property.Setup(p => p.Type).Returns(propertyType.Object);
            serializerProvider.Setup(s => s.GetEdmTypeSerializer(propertyType.Object)).Returns<ODataEdmTypeSerializer>(null);

            var serializer = new ODataEntityTypeSerializer(serializerProvider.Object);

            // Act & Assert
            Assert.Throws<SerializationException>(
                () => serializer.CreateStructuralProperty(property.Object, new EntityInstanceContext { EdmObject = entity }),
                "'Namespace.Name' cannot be serialized using the ODataMediaTypeFormatter.");
        }
Exemplo n.º 7
0
        private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataDeltaWriter writer,
                               ODataSerializerContext writeContext)
        {
            Contract.Assert(writer != null);
            Contract.Assert(writeContext != null);
            Contract.Assert(enumerable != null);
            Contract.Assert(feedType != null);

            ODataDeltaFeed deltaFeed = CreateODataDeltaFeed(enumerable, feedType.AsCollection(), writeContext);

            if (deltaFeed == null)
            {
                throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed));
            }

            // save this for later to support JSON odata.streaming.
            Uri nextPageLink = deltaFeed.NextPageLink;

            deltaFeed.NextPageLink = null;

            //Start writing of the Delta Feed
            writer.WriteStart(deltaFeed);

            //Iterate over all the entries present and select the appropriate write method.
            //Write method creates ODataDeltaDeletedEntry / ODataDeltaDeletedLink / ODataDeltaLink or ODataEntry.
            foreach (object entry in enumerable)
            {
                if (entry == null)
                {
                    throw new SerializationException(SRResources.NullElementInCollection);
                }

                IEdmChangedObject edmChangedObject = entry as IEdmChangedObject;
                if (edmChangedObject == null)
                {
                    throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, enumerable.GetType().FullName));
                }

                switch (edmChangedObject.DeltaKind)
                {
                case EdmDeltaEntityKind.DeletedEntry:
                    WriteDeltaDeletedEntry(entry, writer, writeContext);
                    break;

                case EdmDeltaEntityKind.DeletedLinkEntry:
                    WriteDeltaDeletedLink(entry, writer, writeContext);
                    break;

                case EdmDeltaEntityKind.LinkEntry:
                    WriteDeltaLink(entry, writer, writeContext);
                    break;

                case EdmDeltaEntityKind.Entry:
                {
                    IEdmEntityTypeReference   elementType     = GetEntityType(feedType);
                    ODataEntityTypeSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType) as ODataEntityTypeSerializer;
                    if (entrySerializer == null)
                    {
                        throw new SerializationException(
                                  Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName(), typeof(ODataMediaTypeFormatter).Name));
                    }
                    entrySerializer.WriteDeltaObjectInline(entry, elementType, writer, writeContext);
                    break;
                }

                default:
                    break;
                }
            }

            // Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(feed),
            // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if
            // the next page link is not set when calling WriteStart(feed) but is instead set later on that feed
            // object before calling WriteEnd(), the next page link will be written at the end, as required for
            // odata.streaming=true support.
            if (nextPageLink != null)
            {
                deltaFeed.NextPageLink = nextPageLink;
            }

            //End Writing of the Delta Feed
            writer.WriteEnd();
        }
Exemplo n.º 8
0
        public virtual ODataOperation CreateODataOperation(IEdmOperation operation, FeedContext feedContext, ODataSerializerContext writeContext)
        {
            if (operation == null)
            {
                throw Error.ArgumentNull("operation");
            }

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

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

            ODataMetadataLevel metadataLevel = writeContext.MetadataLevel;
            IEdmModel          model         = writeContext.Model;

            if (metadataLevel != ODataMetadataLevel.FullMetadata)
            {
                return(null);
            }

            ProcedureLinkBuilder builder;
            IEdmAction           action = operation as IEdmAction;

            if (action != null)
            {
                builder = model.GetActionLinkBuilder(action);
            }
            else
            {
                builder = model.GetFunctionLinkBuilder((IEdmFunction)operation);
            }

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

            Uri target = builder.BuildLink(feedContext);

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

            Uri baseUri  = new Uri(writeContext.Url.CreateODataLink(new MetadataPathSegment()));
            Uri metadata = new Uri(baseUri, "#" + operation.FullName());

            ODataOperation odataOperation;

            if (action != null)
            {
                odataOperation = new ODataAction();
            }
            else
            {
                odataOperation = new ODataFunction();
            }
            odataOperation.Metadata = metadata;

            // Always omit the title in minimal/no metadata modes.
            ODataEntityTypeSerializer.EmitTitle(model, operation, odataOperation);

            // Omit the target in minimal/no metadata modes unless it doesn't follow conventions.
            if (metadataLevel == ODataMetadataLevel.FullMetadata || !builder.FollowsConventions)
            {
                odataOperation.Target = target;
            }

            return(odataOperation);
        }
        public void CreateEntry_Works_ToAppendDynamicProperties_ForOpenEntityType()
        {
            // Arrange
            IEdmModel model = SerializationTestsHelpers.SimpleOpenTypeModel();

            IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers");

            IEdmEntityType customerType = model.FindDeclaredType("Default.Customer") as IEdmEntityType;
            Type simpleOpenCustomer = typeof(SimpleOpenCustomer);
            model.SetAnnotationValue(customerType, new ClrTypeAnnotation(simpleOpenCustomer));

            IEdmComplexType addressType = model.FindDeclaredType("Default.Address") as IEdmComplexType;
            Type simpleOpenAddress = typeof(SimpleOpenAddress);
            model.SetAnnotationValue(addressType, new ClrTypeAnnotation(simpleOpenAddress));

            IEdmEnumType enumType = model.FindDeclaredType("Default.SimpleEnum") as IEdmEnumType;
            Type simpleEnumType = typeof(SimpleEnum);
            model.SetAnnotationValue(enumType, new ClrTypeAnnotation(simpleEnumType));

            model.SetAnnotationValue(customerType, new DynamicPropertyDictionaryAnnotation(
                simpleOpenCustomer.GetProperty("CustomerProperties")));

            model.SetAnnotationValue(addressType, new DynamicPropertyDictionaryAnnotation(
                simpleOpenAddress.GetProperty("Properties")));

            ODataSerializerProvider serializerProvider = new DefaultODataSerializerProvider();
            ODataEntityTypeSerializer serializer = new ODataEntityTypeSerializer(serializerProvider);

            SelectExpandNode selectExpandNode = new SelectExpandNode(null, customerType, model);
            ODataSerializerContext writeContext = new ODataSerializerContext
            {
                Model = model,
                Path = new ODataPath(new EntitySetPathSegment(customers))
            };

            SimpleOpenCustomer customer = new SimpleOpenCustomer()
            {
                CustomerId = 991,
                Name = "Name #991",
                Address = new SimpleOpenAddress
                {
                    City = "a city",
                    Street = "a street",
                    Properties = new Dictionary<string, object> { {"ArrayProperty", new[] { "15", "14", "13" } } }
                },
                CustomerProperties = new Dictionary<string, object>()
            };
            customer.CustomerProperties.Add("EnumProperty", SimpleEnum.Fourth);
            customer.CustomerProperties.Add("GuidProperty", new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"));
            customer.CustomerProperties.Add("ListProperty", new List<int>{5,4,3,2,1});
            customer.CustomerProperties.Add("DateTimeProperty", new DateTime(2014, 10, 24));

            EntityInstanceContext entityInstanceContext = new EntityInstanceContext(writeContext,
                customerType.ToEdmTypeReference(false) as IEdmEntityTypeReference, customer);

            // Act
            ODataEntry entry = serializer.CreateEntry(selectExpandNode, entityInstanceContext);

            // Assert
            Assert.Equal(entry.TypeName, "Default.Customer");
            Assert.Equal(7, entry.Properties.Count());

            // Verify the declared properties
            ODataProperty street = Assert.Single(entry.Properties.Where(p => p.Name == "CustomerId"));
            Assert.Equal(991, street.Value);

            ODataProperty city = Assert.Single(entry.Properties.Where(p => p.Name == "Name"));
            Assert.Equal("Name #991", city.Value);

            // Verify the nested open complex property
            ODataProperty address = Assert.Single(entry.Properties.Where(p => p.Name == "Address"));
            ODataComplexValue addressComplexValue = Assert.IsType<ODataComplexValue>(address.Value);
            ODataProperty addressDynamicProperty =
                Assert.Single(addressComplexValue.Properties.Where(p => p.Name == "ArrayProperty"));
            ODataCollectionValue addressCollectionValue =
                Assert.IsType<ODataCollectionValue>(addressDynamicProperty.Value);
            Assert.Equal(new[] { "15", "14", "13" }, addressCollectionValue.Items.OfType<string>().ToList());
            Assert.Equal("Collection(Edm.String)", addressCollectionValue.TypeName);

            // Verify the dynamic properties
            ODataProperty enumProperty = Assert.Single(entry.Properties.Where(p => p.Name == "EnumProperty"));
            ODataEnumValue enumValue = Assert.IsType<ODataEnumValue>(enumProperty.Value);
            Assert.Equal("Fourth", enumValue.Value);
            Assert.Equal("Default.SimpleEnum", enumValue.TypeName);

            ODataProperty guidProperty = Assert.Single(entry.Properties.Where(p => p.Name == "GuidProperty"));
            Assert.Equal(new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"), guidProperty.Value);

            ODataProperty listProperty = Assert.Single(entry.Properties.Where(p => p.Name == "ListProperty"));
            ODataCollectionValue collectionValue = Assert.IsType<ODataCollectionValue>(listProperty.Value);
            Assert.Equal(new List<int>{5,4,3,2,1}, collectionValue.Items.OfType<int>().ToList());
            Assert.Equal("Collection(Edm.Int32)", collectionValue.TypeName);

            ODataProperty dateTimeProperty = Assert.Single(entry.Properties.Where(p => p.Name == "DateTimeProperty"));
            Assert.Equal(new DateTimeOffset(new DateTime(2014, 10, 24)), dateTimeProperty.Value);
        }
        public void CreateEntry_Works_ToAppendNullDynamicProperties_ForOpenEntityType(bool enableNullDynamicProperty, int count)
        {
            // Arrange
            IEdmModel model = SerializationTestsHelpers.SimpleOpenTypeModel();

            IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers");

            IEdmEntityType customerType = model.FindDeclaredType("Default.Customer") as IEdmEntityType;
            Type simpleOpenCustomer = typeof(SimpleOpenCustomer);
            model.SetAnnotationValue(customerType, new ClrTypeAnnotation(simpleOpenCustomer));

            IEdmComplexType addressType = model.FindDeclaredType("Default.Address") as IEdmComplexType;
            Type simpleOpenAddress = typeof(SimpleOpenAddress);
            model.SetAnnotationValue(addressType, new ClrTypeAnnotation(simpleOpenAddress));

            IEdmEnumType enumType = model.FindDeclaredType("Default.SimpleEnum") as IEdmEnumType;
            Type simpleEnumType = typeof(SimpleEnum);
            model.SetAnnotationValue(enumType, new ClrTypeAnnotation(simpleEnumType));

            model.SetAnnotationValue(customerType, new DynamicPropertyDictionaryAnnotation(
                simpleOpenCustomer.GetProperty("CustomerProperties")));

            model.SetAnnotationValue(addressType, new DynamicPropertyDictionaryAnnotation(
                simpleOpenAddress.GetProperty("Properties")));

            ODataSerializerProvider serializerProvider = new DefaultODataSerializerProvider();
            ODataEntityTypeSerializer serializer = new ODataEntityTypeSerializer(serializerProvider);

            HttpConfiguration config = new HttpConfiguration();
            config.SetSerializeNullDynamicProperty(enableNullDynamicProperty);
            HttpRequestMessage request = new HttpRequestMessage();
            request.SetConfiguration(config);
            SelectExpandNode selectExpandNode = new SelectExpandNode(null, customerType, model);
            ODataSerializerContext writeContext = new ODataSerializerContext
            {
                Model = model,
                Path = new ODataPath(new EntitySetPathSegment(customers)),
                Request = request
            };

            SimpleOpenCustomer customer = new SimpleOpenCustomer()
            {
                CustomerId = 991,
                Name = "Name #991",
                Address = new SimpleOpenAddress
                {
                    City = "a city",
                    Street = "a street",
                    Properties = new Dictionary<string, object> { { "ArrayProperty", new[] { "15", "14", "13" } } }
                },
                CustomerProperties = new Dictionary<string, object>()
            };

            customer.CustomerProperties.Add("GuidProperty", new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"));
            customer.CustomerProperties.Add("NullProperty", null);

            EntityInstanceContext entityInstanceContext = new EntityInstanceContext(writeContext,
                customerType.ToEdmTypeReference(false) as IEdmEntityTypeReference, customer);

            // Act
            ODataEntry entry = serializer.CreateEntry(selectExpandNode, entityInstanceContext);

            // Assert
            Assert.Equal(entry.TypeName, "Default.Customer");
            Assert.Equal(count, entry.Properties.Count());

            // Verify the declared properties
            ODataProperty street = Assert.Single(entry.Properties.Where(p => p.Name == "CustomerId"));
            Assert.Equal(991, street.Value);

            ODataProperty city = Assert.Single(entry.Properties.Where(p => p.Name == "Name"));
            Assert.Equal("Name #991", city.Value);

            // Verify the nested open complex property
            ODataProperty address = Assert.Single(entry.Properties.Where(p => p.Name == "Address"));
            ODataComplexValue addressComplexValue = Assert.IsType<ODataComplexValue>(address.Value);
            ODataProperty addressDynamicProperty =
                Assert.Single(addressComplexValue.Properties.Where(p => p.Name == "ArrayProperty"));
            ODataCollectionValue addressCollectionValue =
                Assert.IsType<ODataCollectionValue>(addressDynamicProperty.Value);
            Assert.Equal(new[] { "15", "14", "13" }, addressCollectionValue.Items.OfType<string>().ToList());
            Assert.Equal("Collection(Edm.String)", addressCollectionValue.TypeName);

            // Verify the dynamic properties
            ODataProperty guidProperty = Assert.Single(entry.Properties.Where(p => p.Name == "GuidProperty"));
            Assert.Equal(new Guid("181D3A20-B41A-489F-9F15-F91F0F6C9ECA"), guidProperty.Value);

            ODataProperty nullProperty = entry.Properties.SingleOrDefault(p => p.Name == "NullProperty");
            if (enableNullDynamicProperty)
            {
                Assert.NotNull(nullProperty);
                Assert.Null(nullProperty.Value);
            }
            else
            {
                Assert.Null(nullProperty);
            }
        }