public static ArraySchema GetSchema(ODataCollectionValue colValue)
 {
     var enumerator = colValue.Items.GetEnumerator();
     enumerator.MoveNext();
     var item = enumerator.Current;
     return Schema.CreateArray(GetSchema(item));
 }
        public void WriteObject_WritesValueReturnedFrom_CreateODataCollectionValue()
        {
            // Arrange
            MemoryStream stream = new MemoryStream();
            IODataResponseMessage message = new ODataMessageWrapper(stream);
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings();
            settings.SetContentType(ODataFormat.Atom);
            ODataMessageWriter messageWriter = new ODataMessageWriter(message, settings);
            Mock<ODataCollectionSerializer> serializer = new Mock<ODataCollectionSerializer>(new DefaultODataSerializerProvider());
            ODataSerializerContext writeContext = new ODataSerializerContext { RootElementName = "CollectionName", Model = _model };
            IEnumerable enumerable = new object[0];
            ODataCollectionValue collectionValue = new ODataCollectionValue { TypeName = "NS.Name", Items = new[] { 0, 1, 2 } };

            serializer.CallBase = true;
            serializer
                .Setup(s => s.CreateODataCollectionValue(enumerable, It.Is<IEdmTypeReference>(e => e.Definition == _edmIntType.Definition), writeContext))
                .Returns(collectionValue).Verifiable();

            // Act
            serializer.Object.WriteObject(enumerable, typeof(int[]), messageWriter, writeContext);

            // Assert
            serializer.Verify();
            stream.Seek(0, SeekOrigin.Begin);
            XElement element = XElement.Load(stream);
            Assert.Equal("value", element.Name.LocalName);
            Assert.Equal(3, element.Descendants().Count());
            Assert.Equal(new[] { "0", "1", "2" }, element.Descendants().Select(e => e.Value));
        }
        public void WriteObject_WritesValueReturnedFrom_CreateODataCollectionValue()
        {
            // Arrange
            MemoryStream stream = new MemoryStream();
            IODataResponseMessage message = new ODataMessageWrapper(stream);
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings()
            {
                ODataUri = new ODataUri { ServiceRoot = new Uri("http://any/") }
            };

            settings.SetContentType(ODataFormat.Json);

            ODataMessageWriter messageWriter = new ODataMessageWriter(message, settings);
            Mock<ODataCollectionSerializer> serializer = new Mock<ODataCollectionSerializer>(new DefaultODataSerializerProvider());
            ODataSerializerContext writeContext = new ODataSerializerContext { RootElementName = "CollectionName", Model = _model };
            IEnumerable enumerable = new object[0];
            ODataCollectionValue collectionValue = new ODataCollectionValue { TypeName = "NS.Name", Items = new[] { 0, 1, 2 } };

            serializer.CallBase = true;
            serializer
                .Setup(s => s.CreateODataCollectionValue(enumerable, It.Is<IEdmTypeReference>(e => e.Definition == _edmIntType.Definition), writeContext))
                .Returns(collectionValue).Verifiable();

            // Act
            serializer.Object.WriteObject(enumerable, typeof(int[]), messageWriter, writeContext);

            // Assert
            serializer.Verify();
            stream.Seek(0, SeekOrigin.Begin);
            string result = new StreamReader(stream).ReadToEnd();
            Assert.Equal("{\"@odata.context\":\"http://any/$metadata#Collection(Edm.Int32)\",\"value\":[0,1,2]}", result);
        }
Beispiel #4
0
 public void SetlineItems(ODataCollectionValue values)
 {
     this.lineItems = new Collection<string>();
     foreach (var item in values.Items)
     {
         this.lineItems.Add(item.ToString());
     }
 }
        public void WritingCollectionValueShouldFailWhenNoTypeSpecified()
        {
            var serializer = CreateODataJsonLightValueSerializer(false);

            var collectionValue = new ODataCollectionValue() { Items = new List<string>() };

            Action test = () => serializer.WriteCollectionValue(collectionValue, null, false, false, false);

            test.ShouldThrow<ODataException>().WithMessage(Strings.ODataJsonLightPropertyAndValueSerializer_NoExpectedTypeOrTypeNameSpecifiedForCollectionValueInRequest);
        }
        public void WritingCollectionValueDifferingFromExpectedTypeShouldFail_WithoutEdmPrefix()
        {
            var serializer = CreateODataJsonLightValueSerializer(true);

            var collectionValue = new ODataCollectionValue() { Items = new List<string>(), TypeName = "Collection(Int32)" };

            var stringCollectionTypeRef = EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetString(true));
            Action test = () => serializer.WriteCollectionValue(collectionValue, stringCollectionTypeRef, false, false, false);

            test.ShouldThrow<ODataException>().WithMessage(Strings.ValidationUtils_IncompatibleType("Collection(Edm.Int32)", "Collection(Edm.String)"));
        }
        public void ComplexTypeCollectionRoundtripAtomTest()
        {
            ODataComplexValue subject0 = new ODataComplexValue() { TypeName = "NS.Subject", Properties = new[] { new ODataProperty() { Name = "Name", Value = "English" }, new ODataProperty() { Name = "Score", Value = (Int16)98 } } };
            ODataComplexValue subject1 = new ODataComplexValue() { TypeName = "NS.Subject", Properties = new[] { new ODataProperty() { Name = "Name", Value = "Math" }, new ODataProperty() { Name = "Score", Value = (Int16)90 } } };
            ODataCollectionValue complexCollectionValue = new ODataCollectionValue { TypeName = "Collection(NS.Subject)", Items = new[] { subject0, subject1 } };
            ODataFeedAndEntrySerializationInfo info = new ODataFeedAndEntrySerializationInfo() {
                NavigationSourceEntityTypeName = subject0.TypeName,
                NavigationSourceName = "Subjects",
                ExpectedTypeName = subject0.TypeName
            };

            this.VerifyTypeCollectionRoundtrip(complexCollectionValue, "Subjects", info);
        }
        public void PropertyGettersAndSettersTest()
        {
            string name1 = "ODataPrimitiveProperty";
            object value1 = "Hello world";

            ODataProperty primitiveProperty = new ODataProperty()
            {
                Name = name1,
                Value = value1,
            };

            this.Assert.AreEqual(name1, primitiveProperty.Name, "Expected equal name values.");
            this.Assert.AreSame(value1, primitiveProperty.Value, "Expected reference equal values for property 'Value'.");

            string name2 = "ODataComplexProperty";
            ODataComplexValue value2 = new ODataComplexValue()
            {
                Properties = new[]
                {
                    new ODataProperty() { Name = "One", Value = 1 },
                    new ODataProperty() { Name = "Two", Value = 2 },
                }
            };

            ODataProperty complexProperty = new ODataProperty()
            {
                Name = name2,
                Value = value2,
            };

            this.Assert.AreEqual(name2, complexProperty.Name, "Expected equal name values.");
            this.Assert.AreSame(value2, complexProperty.Value, "Expected reference equal values for property 'Value'.");

            string name3 = "ODataCollectionProperty";
            ODataCollectionValue value3 = new ODataCollectionValue()
            {
                Items = new[] { 1, 2, 3 }
            };

            ODataProperty multiValueProperty = new ODataProperty()
            {
                Name = name3,
                Value = value3,
            };

            this.Assert.AreEqual(name3, multiValueProperty.Name, "Expected equal name values.");
            this.Assert.AreSame(value3, multiValueProperty.Value, "Expected reference equal values for property 'Value'.");
        }
        static ODataAvroWriterTests()
        {
            var type = new EdmEntityType("NS", "SimpleEntry");
            type.AddStructuralProperty("TBoolean", EdmPrimitiveTypeKind.Boolean, true);
            type.AddStructuralProperty("TInt32", EdmPrimitiveTypeKind.Int32, true);
            type.AddStructuralProperty("TCollection", new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetInt64(false))));
            var cpx = new EdmComplexType("NS", "SimpleComplex");
            cpx.AddStructuralProperty("TBinary", EdmPrimitiveTypeKind.Binary, true);
            cpx.AddStructuralProperty("TString", EdmPrimitiveTypeKind.String, true);
            type.AddStructuralProperty("TComplex", new EdmComplexTypeReference(cpx, true));
            TestEntityType = type;

            binary0 = new byte[] { 4, 7 };
            complexValue0 = new ODataComplexValue()
            {
                Properties = new[]
                {
                    new ODataProperty {Name = "TBinary", Value = binary0 ,},
                    new ODataProperty {Name = "TString", Value = "iamstr",},
                },
                TypeName = "NS.SimpleComplex"
            };

            longCollection0 = new[] {7L, 9L};
            var collectionValue0 = new ODataCollectionValue { Items = longCollection0 };

            entry0 = new ODataEntry
            {
                Properties = new[]
                {
                    new ODataProperty {Name = "TBoolean", Value = true,},
                    new ODataProperty {Name = "TInt32", Value = 32,},
                    new ODataProperty {Name = "TComplex", Value = complexValue0,},
                    new ODataProperty {Name = "TCollection", Value = collectionValue0 },
                },
                TypeName = "NS.SimpleEntry"
            };
        }
        private static void AssertODataCollectionValueAreEqual(ODataCollectionValue expectedCollectionValue, ODataCollectionValue actualCollectionValue)
        {
            Assert.IsNotNull(expectedCollectionValue);
            Assert.IsNotNull(actualCollectionValue);
            Assert.AreEqual(expectedCollectionValue.TypeName, actualCollectionValue.TypeName);
            var expectedItemsArray = expectedCollectionValue.Items.OfType<object>().ToArray();
            var actualItemsArray = actualCollectionValue.Items.OfType<object>().ToArray();

            Assert.AreEqual(expectedItemsArray.Length, actualItemsArray.Length);
            for (int i = 0; i < expectedItemsArray.Length; i++)
            {
                var expectedOdataValue = expectedItemsArray[i] as ODataValue;
                var actualOdataValue = actualItemsArray[i] as ODataValue;
                if (expectedOdataValue != null && actualOdataValue != null)
                {
                    AssertODataValueAreEqual(expectedOdataValue, actualOdataValue);
                }
                else
                {
                    Assert.AreEqual(expectedItemsArray[i], actualItemsArray[i]);
                }
            }
        }
        private static object ConvertCollectionValue(ODataCollectionValue collection, IEdmTypeReference propertyType,
            ODataDeserializerProvider deserializerProvider, ODataDeserializerContext readContext)
        {
            IEdmCollectionTypeReference collectionType = propertyType as IEdmCollectionTypeReference;
            Contract.Assert(collectionType != null, "The type for collection must be a IEdmCollectionType.");

            ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(collectionType);
            return deserializer.ReadInline(collection, collectionType, readContext);
        }
        /// <summary>
        /// Creates an <see cref="ODataCollectionValue"/> for the enumerable represented by <paramref name="enumerable"/>.
        /// </summary>
        /// <param name="enumerable">The value of the collection to be created.</param>
        /// <param name="elementType">The element EDM type of the collection.</param>
        /// <param name="writeContext">The serializer context to be used while creating the collection.</param>
        /// <returns>The created <see cref="ODataCollectionValue"/>.</returns>
        public virtual ODataCollectionValue CreateODataCollectionValue(IEnumerable enumerable, IEdmTypeReference elementType,
            ODataSerializerContext writeContext)
        {
            if (writeContext == null)
            {
                throw Error.ArgumentNull("writeContext");
            }
            if (elementType == null)
            {
                throw Error.ArgumentNull("elementType");
            }

            ArrayList valueCollection = new ArrayList();

            if (enumerable != null)
            {
                ODataEdmTypeSerializer itemSerializer = null;
                foreach (object item in enumerable)
                {
                    itemSerializer = itemSerializer ?? SerializerProvider.GetEdmTypeSerializer(elementType);
                    if (itemSerializer == null)
                    {
                        throw new SerializationException(
                            Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName(), typeof(ODataMediaTypeFormatter).Name));
                    }

                    // ODataCollectionWriter expects the individual elements in the collection to be the underlying values and not ODataValues.
                    valueCollection.Add(itemSerializer.CreateODataValue(item, elementType, writeContext).GetInnerValue());
                }
            }

            // Ideally, we'd like to do this:
            // string typeName = _edmCollectionType.FullName();
            // But ODataLib currently doesn't support .FullName() for collections. As a workaround, we construct the
            // collection type name the hard way.
            string typeName = "Collection(" + elementType.FullName() + ")";

            // ODataCollectionValue is only a V3 property, arrays inside Complex Types or Entity types are only supported in V3
            // if a V1 or V2 Client requests a type that has a collection within it ODataLib will throw.
            ODataCollectionValue value = new ODataCollectionValue
            {
                Items = valueCollection,
                TypeName = typeName
            };

            AddTypeNameAnnotationAsNeeded(value, writeContext.MetadataLevel);
            return value;
        }
            internal static object ConvertCollection(ODataCollectionValue collectionValue, IEdmTypeReference edmTypeReference,
                ModelBindingContext bindingContext, ODataDeserializerContext readContext)
            {
                Contract.Assert(collectionValue != null);

                IEdmCollectionTypeReference collectionType = edmTypeReference as IEdmCollectionTypeReference;
                Contract.Assert(collectionType != null);

                ODataCollectionDeserializer deserializer =
                    (ODataCollectionDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType);

                object value = deserializer.ReadInline(collectionValue, collectionType, readContext);
                if (value == null)
                {
                    return null;
                }

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

                Type clrType = bindingContext.ModelType;
                Type elementType;
                if (!clrType.IsCollection(out elementType))
                {
                    // EdmEntityCollectionObject and EdmComplexCollectionObject are collection types.
                    throw new ODataException(String.Format(CultureInfo.InvariantCulture,
                        SRResources.ParameterTypeIsNotCollection, bindingContext.ModelName, clrType));
                }

                IEnumerable newCollection;
                if (CollectionDeserializationHelpers.TryCreateInstance(clrType, collectionType, elementType, out newCollection))
                {
                    collection.AddToCollection(newCollection, elementType, bindingContext.ModelName, bindingContext.ModelType);
                    if (clrType.IsArray)
                    {
                        newCollection = CollectionDeserializationHelpers.ToArray(newCollection, elementType);
                    }

                    return newCollection;
                }

                return null;
            }
 public void CollectionOfPrimitiveCustomInstanceAnnotationOnErrorShouldRoundtrip()
 {
     var originalCollectionValue = new ODataCollectionValue
     {
         TypeName = "Collection(Edm.String)",
         Items = new[] { "value1", "value2" }
     };
     var original = new KeyValuePair<string, ODataValue>("sample.error", originalCollectionValue);
     var error = this.WriteThenReadErrorWithInstanceAnnotation(original);
     var annotation = RunBasicVerificationAndGetAnnotationValue("sample.error", error);
     annotation.Should().BeOfType<ODataCollectionValue>();
     annotation.As<ODataCollectionValue>().Items.Cast<string>().Count().Should().Be(2);
 }
 public void WritingAPrimitiveCollectionValuedAnnotationWithMismatchedMetadataShouldThrow()
 {
     ODataCollectionValue collection = new ODataCollectionValue { Items = new[] { 123.4 } };
     var annotation = AtomInstanceAnnotation.CreateFrom(new ODataInstanceAnnotation("custom.primitiveCollection", collection), /*target*/ null);
     Action test = () => this.serializer.WriteInstanceAnnotation(annotation);
     test.ShouldThrow<ODataException>().WithMessage(Strings.CollectionWithoutExpectedTypeValidator_IncompatibleItemTypeName("Edm.Double", "Edm.Int32"));
 }
Beispiel #16
0
 public void SetCoverColors(ODataCollectionValue values)
 {
     this.CoverColors = new Collection<Color>();
     foreach (var item in values.Items)
     {
         ODataEnumValue enumItem = item as ODataEnumValue;
         this.CoverColors.Add((Color)Enum.Parse(typeof(Color), enumItem.Value));
     }
 }
 public void WriteCollectionValue(ODataCollectionValue collectionValue, IEdmTypeReference metadataTypeReference, bool isTopLevelProperty, bool isInUri, bool isOpenPropertyType)
 {
     this.WriteCollectionVerifier.Should().NotBeNull("WriteCollectionValue was called.");
     this.WriteCollectionVerifier(collectionValue, metadataTypeReference, isTopLevelProperty, isInUri, isOpenPropertyType);
 }
        public void SerializeTopLevelPropertyOfCollectionTypeShouldWork()
        {
            EdmModel model = new EdmModel();

            EdmComplexType complexType = new EdmComplexType("ns", "complex");
            complexType.AddProperty(new EdmStructuralProperty(complexType, "propertyName1", EdmCoreModel.Instance.GetInt32(isNullable: false)));
            complexType.AddProperty(new EdmStructuralProperty(complexType, "propertyName2", EdmCoreModel.Instance.GetString(isNullable: false)));
            model.AddElement(complexType);

            ODataCollectionValue primitiveCollectionValue = new ODataCollectionValue { Items = new[] { "value1", "value2" }};
            primitiveCollectionValue.TypeName = "Collection(Edm.String)";
            ODataProperty primitiveCollectionProperty = new ODataProperty { Name = "PrimitiveCollectionProperty", Value = primitiveCollectionValue };

            string pval = SerializeProperty(model, primitiveCollectionProperty);
            pval.Should().Be("<?xml version=\"1.0\" encoding=\"utf-8\"?><m:value xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" m:context=\"http://odata.org/$metadata#Collection(Edm.String)\" m:type=\"#Collection(String)\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"><m:element>value1</m:element><m:element>value2</m:element></m:value>");
            
            ODataComplexValue complexValue1 = new ODataComplexValue { Properties = new[] { new ODataProperty { Name = "propertyName1", Value = 1 }, new ODataProperty { Name = "propertyName2", Value = "stringValue" } }, TypeName = "ns.complex" };
            ODataComplexValue complexValue2 = new ODataComplexValue { Properties = new[] { new ODataProperty { Name = "propertyName1", Value = 1 }, new ODataProperty { Name = "propertyName2", Value = "stringValue" } }, TypeName = "ns.complex" };
            ODataCollectionValue complexCollectionValue = new ODataCollectionValue { Items = new[] { complexValue1, complexValue2 }, TypeName = "Collection(ns.complex)" };
            ODataProperty complexCollectionProperty = new ODataProperty { Name = "ComplexCollectionProperty", Value = complexCollectionValue };

            string cval = SerializeProperty(model, complexCollectionProperty);
            cval.Should().Be("<?xml version=\"1.0\" encoding=\"utf-8\"?><m:value xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" xmlns:georss=\"http://www.georss.org/georss\" xmlns:gml=\"http://www.opengis.net/gml\" m:context=\"http://odata.org/$metadata#Collection(ns.complex)\" m:type=\"#Collection(ns.complex)\" xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\"><m:element><d:propertyName1 m:type=\"Int32\">1</d:propertyName1><d:propertyName2>stringValue</d:propertyName2></m:element><m:element><d:propertyName1 m:type=\"Int32\">1</d:propertyName1><d:propertyName2>stringValue</d:propertyName2></m:element></m:value>");
        }
        public static ODataCollectionValue ReadCollectionParameterValue(ODataCollectionReader collectionReader)
        {
            List<object> collectionItems = new List<object>();
            while (collectionReader.Read())
            {
                if (collectionReader.State == ODataCollectionReaderState.Completed)
                {
                    break;
                }

                if (collectionReader.State == ODataCollectionReaderState.Value)
                {
                    collectionItems.Add(collectionReader.Item);
                }
            }

            ODataCollectionValue result = new ODataCollectionValue();
            result.Items = collectionItems;
            return result;
        }
        public void WritingNullableCollectionValue()
        {
            EdmModel model = new EdmModel();
            EdmEntityType entityType = new EdmEntityType("NS", "MyTestEntity");
            EdmStructuralProperty key =
                entityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, false);
            entityType.AddKeys(key);
            entityType.AddStructuralProperty(
                "NullableIntNumbers",
                new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetInt32(true))));
            model.AddElement(entityType);

            var collectionValue = new ODataCollectionValue()
            {
                Items = new int?[] { null },
                TypeName = "Collection(Edm.Int32)"
            };

            ODataEntry entry = new ODataEntry()
            {
                Id = new Uri("http://test/Id"),
                TypeName = "NS.MyTestEntity",
                Properties = new[]
                {
                    new ODataProperty { Name = "NullableIntNumbers", Value = collectionValue },
                },
                SerializationInfo = MySerializationInfo
            };

            string outputPayload = this.WriterEntry(model, entry, entityType);
            string expectedPayload = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:d=\"http://docs.oasis-open.org/odata/ns/data\" " +
                    "xmlns:m=\"http://docs.oasis-open.org/odata/ns/metadata\" xmlns:georss=\"http://www.georss.org/georss\" " +
                    "xmlns:gml=\"http://www.opengis.net/gml\" " +
                    "m:context=\"http://odata.org/$metadata#MyTestEntity/$entity\">" +
                    "<id>http://test/Id</id>" +
                    "<category term=\"#NS.MyTestEntity\" scheme=\"http://docs.oasis-open.org/odata/ns/scheme\" />" +
                    "<title />" +
                    "<author><name /></author>" +
                    "<content type=\"application/xml\">" +
                        "<m:properties>" +
                             "<d:NullableIntNumbers m:type=\"#Collection(Int32)\">" +
                                "<m:element m:null=\"true\" />" +
                             "</d:NullableIntNumbers>" +
                        "</m:properties>" +
                    "</content>" +
                "</entry>";

            outputPayload = Regex.Replace(outputPayload, "<updated>[^<]*</updated>", "");
            outputPayload.Should().Be(expectedPayload);
        }
        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 WritingNonNullableCollectionValueWithNullElementShouldThrow()
        {
            EdmModel model = new EdmModel();
            EdmEntityType entityType = new EdmEntityType("NS", "MyTestEntity");
            EdmStructuralProperty key =
                entityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, false);
            entityType.AddKeys(key);
            entityType.AddStructuralProperty(
                "NonNullableIntNumbers",
                new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetInt32(false))));
            model.AddElement(entityType);

            var collectionValue = new ODataCollectionValue()
            {
                Items = new int?[] { null },
                TypeName = "Collection(Edm.Int32)"
            };

            ODataEntry entry = new ODataEntry()
            {
                Id = new Uri("http://test/Id"),
                TypeName = "NS.MyTestEntity",
                Properties = new[]
                {
                    new ODataProperty { Name = "NonNullableIntNumbers", Value = collectionValue },
                },
                SerializationInfo = PropertyAndValueAtomWriterIntegrationTests.MySerializationInfo
            };

            Action test = () => this.WriterEntry(model, entry, entityType);

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

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

            foreach (object entry in collectionValue.Items)
            {
                if (elementType.IsPrimitive())
                {
                    yield return entry;
                }
                else
                {
                    yield return deserializer.ReadInline(entry, elementType, readContext);
                }
            }
        }
Beispiel #24
0
        /// <summary>
        /// Resolve a type name against the provided <paramref name="model"/>. If not payload type name is specified,
        /// derive the type from the model type (if available).
        /// </summary>
        /// <param name="model">The model to use.</param>
        /// <param name="typeReferenceFromMetadata">The type inferred from the model or null if the model is not a user model.</param>
        /// <param name="collectionValue">The value in question to resolve the type for.</param>
        /// <param name="isOpenPropertyType">True if the type name belongs to an open property.</param>
        /// <param name="writerValidator">The writer validator to use for validation.</param>
        /// <returns>A type for the <paramref name="collectionValue"/> or null if no type name is specified and no metadata is available.</returns>
        internal static IEdmTypeReference ResolveAndValidateTypeForCollectionValue(IEdmModel model, IEdmTypeReference typeReferenceFromMetadata, ODataCollectionValue collectionValue, bool isOpenPropertyType, IWriterValidator writerValidator)
        {
            Debug.Assert(model != null, "model != null");

            var typeName = collectionValue.TypeName;

            ValidateIfTypeNameMissing(typeName, model, isOpenPropertyType);

            IEdmType typeFromValue = typeName == null ? null : ResolveAndValidateTypeName(model, typeName, EdmTypeKind.Collection, writerValidator);
            if (typeReferenceFromMetadata != null)
            {
                writerValidator.ValidateTypeKind(EdmTypeKind.Collection, typeReferenceFromMetadata.TypeKind(), typeFromValue);
            }

            IEdmTypeReference typeReferenceFromValue = ResolveTypeFromMetadataAndValue(typeReferenceFromMetadata, typeFromValue == null ? null : typeFromValue.ToTypeReference(), writerValidator);
            if (typeReferenceFromValue != null)
            {
                // update nullability from metadata
                if (typeReferenceFromMetadata != null)
                {
                    typeReferenceFromValue = typeReferenceFromMetadata;
                }

                // validate that the collection type represents a valid Collection type (e.g., is unordered).
                typeReferenceFromValue = writerValidator.ValidateCollectionType(typeReferenceFromValue);
            }

            return typeReferenceFromValue;
        }
        /// <summary>
        /// Adds the type name annotations required for proper json light serialization.
        /// </summary>
        /// <param name="value">The collection value for which the annotations have to be added.</param>
        /// <param name="metadataLevel">The OData metadata level of the response.</param>
        protected internal static void AddTypeNameAnnotationAsNeeded(ODataCollectionValue value, ODataMetadataLevel metadataLevel)
        {
            // ODataLib normally has the caller decide whether or not to serialize properties by leaving properties
            // null when values should not be serialized. The TypeName property is different and should always be
            // provided to ODataLib to enable model validation. A separate annotation is used to decide whether or not
            // to serialize the type name (a null value prevents serialization).

            // Note that this annotation should not be used for Atom or JSON verbose formats, as it will interfere with
            // the correct default behavior for those formats.

            Contract.Assert(value != null);

            // Only add an annotation if we want to override ODataLib's default type name serialization behavior.
            if (ShouldAddTypeNameAnnotation(metadataLevel))
            {
                string typeName;

                // Provide the type name to serialize (or null to force it not to serialize).
                if (ShouldSuppressTypeNameSerialization(metadataLevel))
                {
                    typeName = null;
                }
                else
                {
                    typeName = value.TypeName;
                }

                value.SetAnnotation<SerializationTypeNameAnnotation>(new SerializationTypeNameAnnotation
                {
                    TypeName = typeName
                });
            }
        }
        public void WriteInstanceAnnotation_ForCollectionShouldUseCollectionCodePath()
        {
            var collectionValue = new ODataCollectionValue() { TypeName = "Collection(String)" };
            collectionValue.SetAnnotation(new SerializationTypeNameAnnotation() { TypeName = null });
            const string term = "some.term";
            var verifierCalls = 0;

            this.jsonWriter.WriteNameVerifier = (name) =>
            {
                name.Should().Be("@" + term);
                verifierCalls++;
            };
            this.valueWriter.WriteCollectionVerifier = (value, reference, isTopLevelProperty, isInUri, isOpenProperty) =>
            {
                value.Should().Be(collectionValue);
                reference.Should().BeNull();
                isOpenProperty.Should().BeTrue();
                isTopLevelProperty.Should().BeFalse();
                isInUri.Should().BeFalse();
                verifierCalls.Should().Be(1);
                verifierCalls++;
            };
            this.jsonLightInstanceAnnotationWriter.WriteInstanceAnnotation(new ODataInstanceAnnotation(term, collectionValue));
            verifierCalls.Should().Be(2);
        }
        public void ReadComplexValue_CanReadDynamicCollectionPropertiesForOpenComplexType()
        {
            // Arrange
            ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
            builder.ComplexType<SimpleOpenAddress>();
            builder.EnumType<SimpleEnum>();
            IEdmModel model = builder.GetEdmModel();
            IEdmComplexTypeReference addressTypeReference =
                model.GetEdmTypeReference(typeof(SimpleOpenAddress)).AsComplex();

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

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

            ODataCollectionValue collectionValue = new ODataCollectionValue
            {
                TypeName = "Collection(" + typeof(SimpleEnum).FullName + ")",
                Items = new[] { enumValue, enumValue }
            };

            ODataComplexValue complexValue = new ODataComplexValue
            {
                Properties = new[]
                {
                    // declared properties
                    new ODataProperty { Name = "Street", Value = "My Way #599" },

                    // dynamic properties
                    new ODataProperty { Name = "CollectionProperty", Value = collectionValue }
                },
                TypeName = typeof(SimpleOpenAddress).FullName
            };

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

            // Act
            SimpleOpenAddress address = deserializer.ReadComplexValue(complexValue, addressTypeReference, readContext)
                as SimpleOpenAddress;

            // Assert
            Assert.NotNull(address);

            // Verify the declared properties
            Assert.Equal("My Way #599", address.Street);
            Assert.Null(address.City);

            // Verify the dynamic properties
            Assert.NotNull(address.Properties);
            Assert.Equal(1, address.Properties.Count());

            var collectionValues = Assert.IsType<List<SimpleEnum>>(address.Properties["CollectionProperty"]);
            Assert.NotNull(collectionValues);
            Assert.Equal(2, collectionValues.Count());
            Assert.Equal(SimpleEnum.Third, collectionValues[0]);
            Assert.Equal(SimpleEnum.Third, collectionValues[1]);
        }
Beispiel #28
0
 public void SetEmails(ODataCollectionValue values)
 {
     this.Emails = new Collection<string>();
     foreach (var item in values.Items)
     {
         this.Emails.Add(item != null ? item.ToString() : null);
     }
 }
        private static object ConvertCollectionValue(ODataCollectionValue collection,
            ref IEdmTypeReference propertyType, ODataDeserializerProvider deserializerProvider,
            ODataDeserializerContext readContext)
        {
            IEdmCollectionTypeReference collectionType;
            if (propertyType == null)
            {
                // dynamic collection property
                Contract.Assert(!String.IsNullOrEmpty(collection.TypeName),
                    "ODataLib should have verified that dynamic collection value has a type name " +
                    "since we provided metadata.");

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

            ODataEdmTypeDeserializer deserializer = deserializerProvider.GetEdmTypeDeserializer(collectionType);
            return deserializer.ReadInline(collection, collectionType, readContext);
        }
Beispiel #30
0
 public void SetOrderShelfLifes(ODataCollectionValue values)
 {
     this.OrderShelfLifes = new Collection<TimeSpan>();
     foreach (var item in values.Items)
     {
         this.OrderShelfLifes.Add((TimeSpan)item);
     }
 }