/// <summary>Materializes a complex type property.</summary> /// <param name="propertyType">Type of the complex type to set.</param> /// <param name="complexValue">The OData complex value.</param> internal void MaterializeComplexTypeProperty(Type propertyType, ODataComplexValue complexValue) { //// TODO: we decide whether the type is primitive or complex only based on the payload. If there is a mismatch we throw a random exception. //// We should have a similar check to the one we have for non-projection codepath here. if (complexValue == null || complexValue.HasMaterializedValue()) { return; } ClientTypeAnnotation complexType = null; // TODO: We should call type resolver for complex types for projections if they are not instantiated by the user directly // with "new" operator. At the moment we don't do it at all. Let's be consistent for Collections and call type // resolver as we do in DirectMaterializationPlan (even though this is only for negative cases for Collections as property.IsCollection // must have been false otherwise we would have not end up here). // This bug is about investigating when we actually do call type resolver and fix it so that we call it when needed and don't // call it when we should not (i.e. it should not be called for types created with "new" operator"). if (!string.IsNullOrEmpty(complexValue.TypeName)) { complexType = this.MaterializerContext.ResolveTypeForMaterialization(propertyType, complexValue.TypeName); } else { ClientEdmModel edmModel = this.MaterializerContext.Model; complexType = edmModel.GetClientTypeAnnotation(edmModel.GetOrCreateEdmType(propertyType)); } object complexInstance = this.CreateNewInstance(complexType.EdmType.ToEdmTypeReference(true), complexType.ElementType); this.MaterializeDataValues(complexType, complexValue.Properties, this.MaterializerContext.IgnoreMissingProperties); this.ApplyDataValues(complexType, complexValue.Properties, complexInstance); complexValue.SetMaterializedValue(complexInstance); this.InstanceAnnotationMaterializationPolicy.SetInstanceAnnotations(complexValue, complexInstance); }
/// <summary>Materializes a complex type property.</summary> /// <param name="propertyType">Type of the complex type to set.</param> /// <param name="complexValue">The OData complex value.</param> internal void MaterializeComplexTypeProperty(Type propertyType, ODataComplexValue complexValue) { if (complexValue == null || complexValue.HasMaterializedValue()) { return; } ClientTypeAnnotation complexType = null; if (WebUtil.IsWireTypeCollection(complexValue.TypeName)) { complexType = this.MaterializerContext.ResolveTypeForMaterialization(propertyType, complexValue.TypeName); } else { ClientEdmModel edmModel = this.MaterializerContext.Model; complexType = edmModel.GetClientTypeAnnotation(edmModel.GetOrCreateEdmType(propertyType)); } object complexInstance = this.CreateNewInstance(complexType.EdmType.ToEdmTypeReference(true), propertyType); this.MaterializeDataValues(complexType, complexValue.Properties, this.MaterializerContext.IgnoreMissingProperties); this.ApplyDataValues(complexType, complexValue.Properties, complexInstance); complexValue.SetMaterializedValue(complexInstance); }
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 static void MaterializeComplexTypeProperty(Type propertyType, ODataComplexValue complexValue, bool ignoreMissingProperties, System.Data.Services.Client.ResponseInfo responseInfo) { object instance = null; if ((complexValue != null) && !complexValue.HasMaterializedValue()) { ClientTypeAnnotation actualType = null; if (WebUtil.IsWireTypeCollection(complexValue.TypeName)) { actualType = responseInfo.TypeResolver.ResolveEdmTypeName(propertyType, complexValue.TypeName); } else { ClientEdmModel model = ClientEdmModel.GetModel(responseInfo.MaxProtocolVersion); actualType = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(propertyType)); } instance = Util.ActivatorCreateInstance(propertyType, new object[0]); MaterializeDataValues(actualType, complexValue.Properties, ignoreMissingProperties); ApplyDataValues(actualType, complexValue.Properties, ignoreMissingProperties, responseInfo, instance); complexValue.SetMaterializedValue(instance); } }