/// <summary> /// Reads a value from the message reader. /// </summary> /// <param name="expectedClientType">The expected client type being materialized into.</param> /// <param name="expectedReaderType">The expected type for the underlying reader.</param> protected override void ReadWithExpectedType(IEdmTypeReference expectedClientType, IEdmTypeReference expectedReaderType) { ODataProperty property = this.messageReader.ReadProperty(expectedReaderType); Type underlyingExpectedType = Nullable.GetUnderlyingType(this.ExpectedType) ?? this.ExpectedType; object propertyValue = property.Value; if (expectedClientType.IsCollection()) { Debug.Assert(WebUtil.IsCLRTypeCollection(underlyingExpectedType, this.MaterializerContext.Model) || (SingleResult.HasValue && !SingleResult.Value), "expected type must be collection or single result must be false"); // We are here for two cases: // (1) Something like Execute<ICollection<T>>, in which case the underlyingExpectedType is ICollection<T> // (2) Execute<T> with the bool singleValue = false, in which case underlyingExpectedType is T Type collectionItemType = underlyingExpectedType; Type collectionICollectionType = ClientTypeUtil.GetImplementationType(underlyingExpectedType, typeof(ICollection <>)); object collectionInstance; if (collectionICollectionType != null) { // Case 1 collectionItemType = collectionICollectionType.GetGenericArguments()[0]; collectionInstance = this.CollectionValueMaterializationPolicy.CreateCollectionPropertyInstance(property, underlyingExpectedType); } else { // Case 2 collectionICollectionType = typeof(ICollection <>).MakeGenericType(new Type[] { collectionItemType }); collectionInstance = this.CollectionValueMaterializationPolicy.CreateCollectionPropertyInstance(property, collectionICollectionType); } bool isElementNullable = expectedClientType.AsCollection().ElementType().IsNullable; this.CollectionValueMaterializationPolicy.ApplyCollectionDataValues( property, collectionInstance, collectionItemType, ClientTypeUtil.GetAddToCollectionDelegate(collectionICollectionType), isElementNullable); this.currentValue = collectionInstance; } else if (expectedClientType.IsComplex()) { ODataComplexValue complexValue = propertyValue as ODataComplexValue; Debug.Assert(this.MaterializerContext.Model.GetOrCreateEdmType(underlyingExpectedType).ToEdmTypeReference(false).IsComplex(), "expectedType must be complex type"); this.ComplexValueMaterializationPolicy.MaterializeComplexTypeProperty(underlyingExpectedType, complexValue); this.currentValue = complexValue.GetMaterializedValue(); } else if (expectedClientType.IsEnum()) { this.currentValue = this.EnumValueMaterializationPolicy.MaterializeEnumTypeProperty(underlyingExpectedType, property); } else { Debug.Assert(this.MaterializerContext.Model.GetOrCreateEdmType(underlyingExpectedType).ToEdmTypeReference(false).IsPrimitive(), "expectedType must be primitive type"); this.currentValue = this.PrimitivePropertyConverter.ConvertPrimitiveValue(property.Value, this.ExpectedType); } }
public void MaterializeComplexTypeShouldWork() { ODataComplexValue complexValue = new ODataComplexValue { Properties = new ODataProperty[] { new ODataProperty { Name = "age", Value = 11 }, new ODataProperty { Name = "name", Value = "June" }, new ODataProperty { Name = "color", Value = new ODataEnumValue("blue") }, new ODataProperty { Name = "primitives", Value = new ODataCollectionValue { TypeName = "Edm.Int32", Items = new List <int> { 1, 2, 3 } } }, new ODataProperty { Name = "enums", Value = new ODataCollectionValue { TypeName = "color", Items = new List <ODataEnumValue> { new ODataEnumValue("white"), new ODataEnumValue("blue") } } } } }; this.CreatePrimitiveValueMaterializationPolicy().MaterializeComplexTypeProperty(typeof(ComplexType), complexValue); complexValue.HasMaterializedValue().Should().BeTrue(); var complex = complexValue.GetMaterializedValue().As <ComplexType>(); complex.Name.Should().Be("June"); complex.Age.Should().Be(11); complex.Color.Should().Be(Color.Blue); complex.Primitives.Should().ContainInOrder(1, 2, 3); complex.Enums.Should().ContainInOrder(Color.White, Color.Blue); }
public void ComplexWithPrimitiveValueShouldMaterialize() { ODataComplexValue pointComplexValue = new ODataComplexValue() { Properties = new ODataProperty[] { new ODataProperty() { Name = "X", Value = 15 }, new ODataProperty() { Name = "Y", Value = 18 } } }; this.CreatePrimitiveValueMaterializationPolicy().MaterializeComplexTypeProperty(typeof(CollectionValueMaterializationPolicyTests.Point), pointComplexValue); pointComplexValue.HasMaterializedValue().Should().BeTrue(); var point = pointComplexValue.GetMaterializedValue().As <CollectionValueMaterializationPolicyTests.Point>(); point.X.Should().Be(15); point.Y.Should().Be(18); }
protected override void ReadFromMessageReader(ODataMessageReader reader, IEdmTypeReference expectedType) { ODataProperty collectionProperty = reader.ReadProperty(expectedType); Type type = Nullable.GetUnderlyingType(base.ExpectedType) ?? base.ExpectedType; object obj2 = collectionProperty.Value; if (expectedType.IsCollection()) { object obj3; Type collectionItemType = type; Type implementationType = ClientTypeUtil.GetImplementationType(type, typeof(ICollection <>)); if (implementationType != null) { collectionItemType = implementationType.GetGenericArguments()[0]; obj3 = ODataMaterializer.CreateCollectionInstance(collectionProperty, type, base.ResponseInfo); } else { implementationType = typeof(ICollection <>).MakeGenericType(new Type[] { collectionItemType }); obj3 = ODataMaterializer.CreateCollectionInstance(collectionProperty, implementationType, base.ResponseInfo); } ODataMaterializer.ApplyCollectionDataValues(collectionProperty, base.ResponseInfo.IgnoreMissingProperties, base.ResponseInfo, obj3, collectionItemType, ODataMaterializer.GetAddToCollectionDelegate(implementationType)); this.currentValue = obj3; } else if (expectedType.IsComplex()) { ODataComplexValue complexValue = obj2 as ODataComplexValue; ODataMaterializer.MaterializeComplexTypeProperty(type, complexValue, base.ResponseInfo.IgnoreMissingProperties, base.ResponseInfo); this.currentValue = complexValue.GetMaterializedValue(); } else { ODataMaterializer.MaterializePrimitiveDataValue(base.ExpectedType, collectionProperty); this.currentValue = collectionProperty.GetMaterializedValue(); } }