/// <inheritdoc /> public override ODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType) { if (edmType == null) { throw new ArgumentNullException(nameof(edmType)); } switch (edmType.TypeKind()) { case EdmTypeKind.Entity: case EdmTypeKind.Complex: return(_serviceProvider.GetRequiredService <ODataResourceDeserializer>()); case EdmTypeKind.Enum: return(_serviceProvider.GetRequiredService <ODataEnumDeserializer>()); case EdmTypeKind.Primitive: return(_serviceProvider.GetRequiredService <ODataPrimitiveDeserializer>()); case EdmTypeKind.Collection: IEdmCollectionTypeReference collectionType = edmType.AsCollection(); if (collectionType.ElementType().IsEntity() || collectionType.ElementType().IsComplex()) { return(_serviceProvider.GetRequiredService <ODataResourceSetDeserializer>()); } else { return(_serviceProvider.GetRequiredService <ODataCollectionDeserializer>()); } default: return(null); } }
public void WriteObjectInline_WritesEachEntityInstance() { // Arrange var mockSerializerProvider = new Mock <ODataSerializerProvider>(MockBehavior.Strict, _model); var mockCustomerSerializer = new Mock <ODataSerializer>(MockBehavior.Strict, ODataPayloadKind.Entry); var mockWriter = new Mock <ODataWriter>(); mockSerializerProvider .Setup(p => p.CreateEdmTypeSerializer(_customersType.ElementType())) .Returns(mockCustomerSerializer.Object); mockCustomerSerializer .Setup(s => s.WriteObjectInline(_customers[0], It.IsAny <ODataWriter>(), _writeContext)) .Verifiable(); mockCustomerSerializer .Setup(s => s.WriteObjectInline(_customers[1], It.IsAny <ODataWriter>(), _writeContext)) .Verifiable(); mockWriter .Setup(w => w.WriteStart(It.IsAny <ODataFeed>())) .Callback((ODataFeed feed) => { Assert.Equal("http://schemas.datacontract.org/2004/07/", feed.Id); }) .Verifiable(); _serializer = new ODataFeedSerializer(_customersType, mockSerializerProvider.Object); // Act _serializer.WriteObjectInline(_customers, mockWriter.Object, _writeContext); // Assert mockSerializerProvider.Verify(); mockCustomerSerializer.Verify(); mockWriter.Verify(); }
/// <summary> /// Returns the appropriate deserializer for the given IEdmType. /// /// The structure of this method is copied from DefaultODataDeserializerProvider, however the difference is /// that the Migration deserializers are hardwired in (use them all or use none of them). /// </summary> /// <param name="edmType">The edm type to obtain the deserializer for.</param> /// <returns>The appropriate deserializer for the given edm type.</returns> public override ODataEdmTypeDeserializer GetEdmTypeDeserializer(IEdmTypeReference edmType) { if (edmType == null) { throw new ArgumentNullException(nameof(edmType)); } switch (edmType.TypeKind()) { case EdmTypeKind.Entity: case EdmTypeKind.Complex: // Resources might contain non-V3 compatible types, return(new ODataMigrationResourceDeserializer(this)); case EdmTypeKind.Enum: return(new ODataEnumDeserializer()); case EdmTypeKind.Primitive: return(new ODataPrimitiveDeserializer()); case EdmTypeKind.Collection: IEdmCollectionTypeReference collectionType = edmType.AsCollection(); if (collectionType.ElementType().IsEntity() || collectionType.ElementType().IsComplex()) { return(new ODataResourceSetDeserializer(this)); } else { return(new ODataMigrationCollectionDeserializer(this)); } default: return(null); } }
public ODataFeedSerializer(IEdmCollectionTypeReference edmCollectionType, ODataSerializerProvider serializerProvider) : base(edmCollectionType, ODataPayloadKind.Feed, serializerProvider) { _edmCollectionType = edmCollectionType; if (!edmCollectionType.ElementType().IsEntity()) { throw Error.NotSupported(SRResources.TypeMustBeEntityCollection, edmCollectionType.ElementType().FullName(), typeof(IEdmEntityType).Name); } }
/// <summary> /// Initializes a new instance of the <see cref="ODataFeedDeserializer"/> class. /// </summary> /// <param name="edmType">The entity collection type that this deserializer can read.</param> /// <param name="deserializerProvider">The deserializer provider to use to read inner objects.</param> public ODataFeedDeserializer(IEdmCollectionTypeReference edmType, ODataDeserializerProvider deserializerProvider) : base(edmType, ODataPayloadKind.Feed, deserializerProvider) { CollectionType = edmType; if (!edmType.ElementType().IsEntity()) { throw Error.Argument("edmType", SRResources.TypeMustBeEntityCollection, edmType.ElementType().FullName(), typeof(IEdmEntityType).Name); } EntityType = CollectionType.ElementType().AsEntity(); }
private static object ConvertResourceSet(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference, ODataDeserializerContext readContext) { IEdmCollectionTypeReference collectionType = edmTypeReference.AsCollection(); EdmEntitySet tempEntitySet = null; if (collectionType.ElementType().IsEntity()) { tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp", collectionType.ElementType().AsEntity().EntityDefinition()); } // TODO: Sam xu, can we use the parameter-less overload ODataReader odataReader = oDataMessageReader.CreateODataUriParameterResourceSetReader(tempEntitySet, collectionType.ElementType().AsStructured().StructuredDefinition()); ODataResourceSetWrapper resourceSet = odataReader.ReadResourceOrResourceSet() as ODataResourceSetWrapper; ODataDeserializerProvider deserializerProvider = readContext.Request.GetDeserializerProvider(); ODataResourceSetDeserializer resourceSetDeserializer = (ODataResourceSetDeserializer)deserializerProvider.GetEdmTypeDeserializer(collectionType); object result = resourceSetDeserializer.ReadInline(resourceSet, collectionType, readContext); IEnumerable enumerable = result as IEnumerable; if (enumerable != null) { IEnumerable newEnumerable = enumerable; if (collectionType.ElementType().IsEntity()) { newEnumerable = CovertResourceSetIds(enumerable, resourceSet, collectionType, readContext); } if (readContext.IsUntyped) { return(newEnumerable.ConvertToEdmObject(collectionType)); } else { IEdmTypeReference elementTypeReference = collectionType.ElementType(); Type elementClrType = EdmLibHelpers.GetClrType(elementTypeReference, readContext.Model); IEnumerable castedResult = CastMethodInfo.MakeGenericMethod(elementClrType) .Invoke(null, new object[] { newEnumerable }) as IEnumerable; return(castedResult); } } return(null); }
private void Initialize(IEdmCollectionTypeReference edmType) { if (edmType == null) { throw Error.ArgumentNull("edmType"); } if (!edmType.ElementType().IsComplex()) { throw Error.Argument("edmType", SRResources.UnexpectedElementType, edmType.ElementType().ToTraceString(), edmType.ToTraceString(), typeof(IEdmComplexType).Name); } _edmType = edmType; }
/// <inheritdoc /> public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext) { if (item == null) { return(null); } if (edmType == null) { throw Error.ArgumentNull("edmType"); } if (!edmType.IsCollection()) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeDeserialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter))); } IEdmCollectionTypeReference collectionType = edmType.AsCollection(); IEdmTypeReference elementType = collectionType.ElementType(); ODataCollectionValue collection = item as ODataCollectionValue; if (collection == null) { throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataCollectionValue).Name); } // Recursion guard to avoid stack overflows RuntimeHelpers.EnsureSufficientExecutionStack(); return(ReadCollectionValue(collection, elementType, readContext)); }
/// <inheritdoc /> public override object Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } IEdmTypeReference edmType = readContext.GetEdmType(type); Contract.Assert(edmType != null); if (!edmType.IsCollection()) { throw Error.Argument("type", SRResources.ArgumentMustBeOfType, EdmTypeKind.Collection); } IEdmCollectionTypeReference collectionType = edmType.AsCollection(); IEdmTypeReference elementType = collectionType.ElementType(); IEnumerable result = ReadInline(ReadCollection(messageReader, elementType), edmType, readContext) as IEnumerable; if (result != null && readContext.IsUntyped && elementType.IsComplex()) { EdmComplexObjectCollection complexCollection = new EdmComplexObjectCollection(collectionType); foreach (EdmComplexObject complexObject in result) { complexCollection.Add(complexObject); } return(complexCollection); } return(result); }
/// <inheritdoc /> public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext) { if (item == null) { return(null); } if (edmType == null) { throw Error.ArgumentNull("edmType"); } if (!edmType.IsCollection()) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeDeserialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter))); } IEdmCollectionTypeReference collectionType = edmType.AsCollection(); IEdmTypeReference elementType = collectionType.ElementType(); ODataCollectionValue collection = item as ODataCollectionValue; if (collection == null) { throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataCollectionValue).Name); } // Recursion guard to avoid stack overflows RuntimeHelpers.EnsureSufficientExecutionStack(); IEnumerable result = ReadCollectionValue(collection, elementType, readContext); if (result != null) { if (readContext.IsUntyped && elementType.IsComplex()) { EdmComplexObjectCollection complexCollection = new EdmComplexObjectCollection(collectionType); foreach (EdmComplexObject complexObject in result) { complexCollection.Add(complexObject); } return(complexCollection); } else if (readContext.IsUntyped && elementType.IsEnum()) { EdmEnumObjectCollection enumCollection = new EdmEnumObjectCollection(collectionType); foreach (EdmEnumObject enumObject in result) { enumCollection.Add(enumObject); } return(enumCollection); } else { Type elementClrType = EdmLibHelpers.GetClrType(elementType, readContext.Model); IEnumerable castedResult = _castMethodInfo.MakeGenericMethod(elementClrType).Invoke(null, new object[] { result }) as IEnumerable; return(castedResult); } } return(null); }
protected override ODataEntryDeserializer CreateDeserializer(IEdmTypeReference edmType) { if (edmType != null) { switch (edmType.TypeKind()) { case EdmTypeKind.Entity: return(new ODataEntityDeserializer(edmType.AsEntity(), this)); case EdmTypeKind.Primitive: return(new ODataPrimitiveDeserializer(edmType.AsPrimitive())); case EdmTypeKind.Complex: return(new ODataComplexTypeDeserializer(edmType.AsComplex(), this)); case EdmTypeKind.Collection: IEdmCollectionTypeReference collectionType = edmType.AsCollection(); if (collectionType.ElementType().IsEntity()) { return(new ODataFeedDeserializer(collectionType, this)); } else { return(new ODataCollectionDeserializer(collectionType, this)); } } } return(null); }
/// <inheritdoc /> public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType) { if (edmType == null) { throw Error.ArgumentNull("edmType"); } switch (edmType.TypeKind()) { case EdmTypeKind.Primitive: return(_primitiveSerializer); case EdmTypeKind.Collection: IEdmCollectionTypeReference collectionType = edmType.AsCollection(); if (collectionType.ElementType().IsEntity()) { return(_feedSerializer); } else { return(_collectionSerializer); } case EdmTypeKind.Complex: return(_complexTypeSerializer); case EdmTypeKind.Entity: return(_entityTypeSerializer); default: return(null); } }
public void ReadInline_Calls_ReadCollectionValue() { // Arrange Mock <ODataCollectionDeserializer> deserializer = new Mock <ODataCollectionDeserializer>(DeserializerProvider); ODataCollectionValue collectionValue = new ODataCollectionValue(); ODataDeserializerContext readContext = new ODataDeserializerContext(); deserializer.CallBase = true; deserializer.Setup(s => s.ReadCollectionValue(collectionValue, IntCollectionType.ElementType(), readContext)).Verifiable(); // Act deserializer.Object.ReadInline(collectionValue, IntCollectionType, readContext); // Assert deserializer.Verify(); }
public override ODataSerializer CreateEdmTypeSerializer(IEdmTypeReference edmType) { if (edmType == null) { throw Error.ArgumentNull("edmType"); } switch (edmType.TypeKind()) { case EdmTypeKind.Primitive: return(new ODataPrimitiveSerializer(edmType.AsPrimitive())); case EdmTypeKind.Collection: IEdmCollectionTypeReference collectionType = edmType.AsCollection(); if (collectionType.ElementType().IsEntity()) { return(new ODataFeedSerializer(collectionType, this)); } else { return(new ODataCollectionSerializer(collectionType, this)); } case EdmTypeKind.Complex: return(new ODataComplexTypeSerializer(edmType.AsComplex(), this)); case EdmTypeKind.Entity: return(new ODataEntityTypeSerializer(edmType.AsEntity(), this)); default: throw Error.InvalidOperation(SRResources.TypeCannotBeSerialized, edmType.ToTraceString(), typeof(ODataMediaTypeFormatter).Name); } }
/// <summary> /// Gets the parameter value. /// </summary> /// <param name="parameterName">The name of the parameter.</param> /// <returns> The value of the parameter. </returns> public object GetParameterValue(string parameterName) { if (String.IsNullOrEmpty(parameterName)) { throw Error.ArgumentNullOrEmpty("parameterName"); } string paramValue; if (Values.TryGetValue(parameterName, out paramValue)) { IEdmOperationParameter edmParam = Function.FindParameter(parameterName); if (edmParam != null) { IEdmTypeReference edmType = edmParam.Type; if (edmParam.Type.IsCollection()) { IEdmCollectionTypeReference collectionTypeReference = edmParam.Type.AsCollection(); edmType = collectionTypeReference.ElementType(); } // for entity or collection of entity, return the string literal from Uri. if (edmType.Definition.TypeKind == EdmTypeKind.Entity) { return(paramValue); } return(ODataUriUtils.ConvertFromUriLiteral(paramValue, ODataVersion.V4, _edmModel, edmParam.Type)); } } throw Error.Argument("parameterName", SRResources.FunctionParameterNotFound, parameterName); }
private static void ProcessResourceSet(object feed, IEdmCollectionTypeReference resourceSetType, ODataDeserializerContext readContext, ODataDeserializerProvider deserializerProvider, Dictionary <string, object> payload, string parameterName) { ODataResourceSetDeserializer resourceSetDeserializer = (ODataResourceSetDeserializer)deserializerProvider.GetEdmTypeDeserializer(resourceSetType); object result = resourceSetDeserializer.ReadInline(feed, resourceSetType, readContext); IEdmTypeReference elementTypeReference = resourceSetType.ElementType(); Contract.Assert(elementTypeReference.IsStructured()); IEnumerable enumerable = result as IEnumerable; if (enumerable != null) { if (readContext.IsUntyped) { payload[parameterName] = enumerable.ConvertToEdmObject(resourceSetType); } else { Type elementClrType = EdmLibHelpers.GetClrType(elementTypeReference, readContext.Model); IEnumerable castedResult = _castMethodInfo.MakeGenericMethod(elementClrType) .Invoke(null, new[] { result }) as IEnumerable; payload[parameterName] = castedResult; } } }
/// <summary> /// Creates an <see cref="ODataEdmTypeDeserializer"/> that can deserialize payloads of the given <paramref name="edmType"/>. /// </summary> /// <param name="edmType">The EDM type that the created deserializer can handle.</param> /// <returns>The created deserializer.</returns> /// <remarks> Override this method if you want to use a custom deserializer. <see cref="GetEdmTypeDeserializer"/> calls into this method and caches the result.</remarks> public virtual ODataEdmTypeDeserializer CreateEdmTypeDeserializer(IEdmTypeReference edmType) { if (edmType == null) { throw Error.ArgumentNull("edmType"); } switch (edmType.TypeKind()) { case EdmTypeKind.Entity: return(new ODataEntityDeserializer(edmType.AsEntity(), this)); case EdmTypeKind.Primitive: return(new ODataPrimitiveDeserializer(edmType.AsPrimitive())); case EdmTypeKind.Complex: return(new ODataComplexTypeDeserializer(edmType.AsComplex(), this)); case EdmTypeKind.Collection: IEdmCollectionTypeReference collectionType = edmType.AsCollection(); if (collectionType.ElementType().IsEntity()) { return(new ODataFeedDeserializer(collectionType, this)); } else { return(new ODataCollectionDeserializer(collectionType, this)); } default: return(null); } }
/// <inheritdoc /> public override async Task <object> ReadAsync(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext) { if (messageReader == null) { throw Error.ArgumentNull("messageReader"); } if (readContext == null) { throw new ArgumentNullException(nameof(readContext)); } IEdmTypeReference edmType = readContext.GetEdmType(type); Contract.Assert(edmType != null); if (!edmType.IsCollection()) { throw Error.Argument("type", SRResources.ArgumentMustBeOfType, EdmTypeKind.Collection); } IEdmCollectionTypeReference collectionType = edmType.AsCollection(); IEdmTypeReference elementType = collectionType.ElementType(); ODataCollectionReader reader = await messageReader.CreateODataCollectionReaderAsync(elementType).ConfigureAwait(false); return(ReadInline(await ReadCollectionAsync(reader).ConfigureAwait(false), edmType, readContext)); }
internal static object ConvertFeed(ODataMessageReader oDataMessageReader, IEdmTypeReference edmTypeReference, ODataDeserializerContext readContext) { IEdmCollectionTypeReference collectionType = edmTypeReference.AsCollection(); EdmEntitySet tempEntitySet = new EdmEntitySet(readContext.Model.EntityContainer, "temp", collectionType.ElementType().AsEntity().EntityDefinition()); ODataReader odataReader = oDataMessageReader.CreateODataFeedReader(tempEntitySet, collectionType.ElementType().AsEntity().EntityDefinition()); ODataFeedWithEntries feed = ODataEntityDeserializer.ReadEntryOrFeed(odataReader) as ODataFeedWithEntries; ODataFeedDeserializer feedDeserializer = (ODataFeedDeserializer)DeserializerProvider.GetEdmTypeDeserializer(collectionType); object result = feedDeserializer.ReadInline(feed, collectionType, readContext); IEnumerable enumerable = result as IEnumerable; if (enumerable != null) { IEnumerable newEnumerable = CovertFeedIds(enumerable, feed, collectionType, readContext); if (readContext.IsUntyped) { EdmEntityObjectCollection entityCollection = new EdmEntityObjectCollection(collectionType); foreach (EdmEntityObject entity in newEnumerable) { entityCollection.Add(entity); } return(entityCollection); } else { IEdmTypeReference elementTypeReference = collectionType.ElementType(); Type elementClrType = EdmLibHelpers.GetClrType(elementTypeReference, readContext.Model); IEnumerable castedResult = CastMethodInfo.MakeGenericMethod(elementClrType) .Invoke(null, new object[] { newEnumerable }) as IEnumerable; return(castedResult); } } return(null); }
public void GetEdmType_Returns_EdmTypeInitializedByCtor() { IEdmEntityType _entityType = new EdmEntityType("NS", "Entity"); var edmObject = new EdmChangedObjectCollection(_entityType); IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)edmObject.GetEdmType(); Assert.Same(_entityType, collectionTypeReference.ElementType().Definition); }
internal void WriteCollectionValue(ODataCollectionValue collectionValue, IEdmTypeReference metadataTypeReference, bool isOpenPropertyType) { this.IncreaseRecursionDepth(); base.JsonWriter.StartObjectScope(); string typeName = collectionValue.TypeName; IEdmCollectionTypeReference type = (IEdmCollectionTypeReference)WriterValidationUtils.ResolveTypeNameForWriting(base.Model, metadataTypeReference, ref typeName, EdmTypeKind.Collection, isOpenPropertyType); string itemTypeNameFromCollection = null; if (typeName != null) { itemTypeNameFromCollection = ValidationUtils.ValidateCollectionTypeName(typeName); } SerializationTypeNameAnnotation annotation = collectionValue.GetAnnotation <SerializationTypeNameAnnotation>(); if (annotation != null) { typeName = annotation.TypeName; } if (typeName != null) { base.JsonWriter.WriteName("__metadata"); base.JsonWriter.StartObjectScope(); base.JsonWriter.WriteName("type"); base.JsonWriter.WriteValue(typeName); base.JsonWriter.EndObjectScope(); } base.JsonWriter.WriteDataArrayName(); base.JsonWriter.StartArrayScope(); IEnumerable items = collectionValue.Items; if (items != null) { IEdmTypeReference propertyTypeReference = (type == null) ? null : type.ElementType(); CollectionWithoutExpectedTypeValidator collectionValidator = new CollectionWithoutExpectedTypeValidator(itemTypeNameFromCollection); DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = null; foreach (object obj2 in items) { ValidationUtils.ValidateCollectionItem(obj2, false); ODataComplexValue complexValue = obj2 as ODataComplexValue; if (complexValue != null) { if (duplicatePropertyNamesChecker == null) { duplicatePropertyNamesChecker = base.CreateDuplicatePropertyNamesChecker(); } this.WriteComplexValue(complexValue, propertyTypeReference, false, duplicatePropertyNamesChecker, collectionValidator); duplicatePropertyNamesChecker.Clear(); } else { this.WritePrimitiveValue(obj2, collectionValidator, propertyTypeReference); } } } base.JsonWriter.EndArrayScope(); base.JsonWriter.EndObjectScope(); this.DecreaseRecursionDepth(); }
/// <inheritdoc /> public ODataEdmTypeSerializer GetEdmTypeSerializer(HttpContext context, IEdmTypeReference edmType) { if (context == null) { throw Error.ArgumentNull("context"); } if (edmType == null) { throw Error.ArgumentNull("edmType"); } IServiceProvider provider = context.RequestServices; switch (edmType.TypeKind()) { case EdmTypeKind.Enum: return(provider.GetRequiredService <ODataEnumSerializer>()); case EdmTypeKind.Primitive: return(provider.GetRequiredService <ODataPrimitiveSerializer>()); case EdmTypeKind.Collection: IEdmCollectionTypeReference collectionType = edmType.AsCollection(); if (collectionType.Definition.IsDeltaFeed()) { return(provider.GetRequiredService <ODataDeltaFeedSerializer>()); } else if (collectionType.ElementType().IsEntity() || collectionType.ElementType().IsComplex()) { return(provider.GetRequiredService <ODataResourceSetSerializer>()); } else { return(provider.GetRequiredService <ODataCollectionSerializer>()); } case EdmTypeKind.Complex: case EdmTypeKind.Entity: return(provider.GetRequiredService <ODataResourceSerializer>()); default: return(null); } }
public void WriteObjectInline_WritesEachEntityInstance() { // Arrange Mock <ODataEdmTypeSerializer> customerSerializer = new Mock <ODataEdmTypeSerializer>(ODataPayloadKind.Entry); ODataSerializerProvider provider = ODataTestUtil.GetMockODataSerializerProvider(customerSerializer.Object); var mockWriter = new Mock <ODataWriter>(); customerSerializer.Setup(s => s.WriteObjectInline(_customers[0], _customersType.ElementType(), mockWriter.Object, _writeContext)).Verifiable(); customerSerializer.Setup(s => s.WriteObjectInline(_customers[1], _customersType.ElementType(), mockWriter.Object, _writeContext)).Verifiable(); _serializer = new ODataFeedSerializer(provider); // Act _serializer.WriteObjectInline(_customers, _customersType, mockWriter.Object, _writeContext); // Assert customerSerializer.Verify(); }
public ODataCollectionSerializer(IEdmCollectionTypeReference edmCollectionType, ODataSerializerProvider serializerProvider) : base(edmCollectionType, ODataPayloadKind.Collection, serializerProvider) { Contract.Assert(edmCollectionType != null); _edmCollectionType = edmCollectionType; IEdmTypeReference itemType = edmCollectionType.ElementType(); Contract.Assert(itemType != null); _edmItemType = itemType; }
public static IEdmTypeReference GetElementTypeOrSelf(this IEdmTypeReference typeReference) { if (typeReference.TypeKind() == EdmTypeKind.Collection) { IEdmCollectionTypeReference collectType = typeReference.AsCollection(); return(collectType.ElementType()); } return(typeReference); }
internal static IEdmTypeReference GetCollectionItemType(this IEdmTypeReference typeReference) { IEdmCollectionTypeReference type = typeReference.AsCollectionOrNull(); if (type != null) { return(type.ElementType()); } return(null); }
private void WriteFeed(object graph, ODataWriter writer, ODataSerializerContext writeContext) { ODataSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(_edmCollectionType.ElementType()); if (entrySerializer == null) { throw Error.NotSupported(SRResources.TypeCannotBeSerialized, _edmCollectionType.ElementType(), typeof(ODataMediaTypeFormatter).Name); } Contract.Assert(entrySerializer.ODataPayloadKind == ODataPayloadKind.Entry); IEnumerable enumerable = graph as IEnumerable; // Data to serialize if (enumerable != null) { ODataFeed feed = new ODataFeed(); if (writeContext.EntitySet != null) { IEntitySetLinkBuilder linkBuilder = SerializerProvider.EdmModel.GetEntitySetLinkBuilder(writeContext.EntitySet); Uri feedSelfLink = linkBuilder.BuildFeedSelfLink(new FeedContext(writeContext.EntitySet, writeContext.UrlHelper, graph)); if (feedSelfLink != null) { feed.SetAnnotation(new AtomFeedMetadata() { SelfLink = new AtomLinkMetadata() { Relation = SelfLinkRelation, Href = feedSelfLink } }); } } // TODO: Bug 467590: remove the hardcoded feed id. Get support for it from the model builder ? feed.Id = FeedNamespace + _edmCollectionType.FullName(); // If we have more OData format specific information apply it now. ODataResult odataFeedAnnotations = graph as ODataResult; if (odataFeedAnnotations != null) { feed.Count = odataFeedAnnotations.Count; feed.NextPageLink = odataFeedAnnotations.NextPageLink; } writer.WriteStart(feed); foreach (object entry in enumerable) { entrySerializer.WriteObjectInline(entry, writer, writeContext); } writer.WriteEnd(); } }
/// <inheritdoc /> public sealed override object ReadInline(object item, IEdmTypeReference edmType, ODataDeserializerContext readContext) { if (item == null) { return(null); } if (edmType == null) { throw new ArgumentNullException(nameof(edmType)); } if (readContext == null) { throw new ArgumentNullException(nameof(readContext)); } if (!edmType.IsCollection()) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeDeserialized, edmType.ToTraceString())); } IEdmCollectionTypeReference collectionType = edmType.AsCollection(); IEdmTypeReference elementType = collectionType.ElementType(); ODataCollectionValue collection = item as ODataCollectionValue; if (collection == null) { throw Error.Argument("item", SRResources.ArgumentMustBeOfType, typeof(ODataCollectionValue).Name); } // Recursion guard to avoid stack overflows RuntimeHelpers.EnsureSufficientExecutionStack(); IEnumerable result = ReadCollectionValue(collection, elementType, readContext); if (result != null) { if (readContext.IsNoClrType && elementType.IsEnum()) { return(result.ConvertToEdmObject(collectionType)); } else { Type elementClrType = readContext.Model.GetClrType(elementType); IEnumerable castedResult = _castMethodInfo.MakeGenericMethod(elementClrType).Invoke(null, new object[] { result }) as IEnumerable; return(castedResult); } } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="ODataCollectionSerializer"/> class. /// </summary> /// <param name="edmType">The edm collection type this serializer instance can serialize.</param> /// <param name="serializerProvider">The serializer provider to use to serialize nested objects.</param> public ODataCollectionSerializer(IEdmCollectionTypeReference edmType, ODataSerializerProvider serializerProvider) : base(edmType, ODataPayloadKind.Collection, serializerProvider) { IEdmTypeReference itemType = edmType.ElementType(); if (itemType == null) { throw Error.Argument("edmType", SRResources.ItemTypeOfCollectionNull, edmType.FullName()); } CollectionType = edmType; ElementType = itemType; }
internal static IEnumerable CovertFeedIds(IEnumerable sources, ODataFeedWithEntries feed, IEdmCollectionTypeReference collectionType, ODataDeserializerContext readContext) { IEdmEntityTypeReference entityTypeReference = collectionType.ElementType().AsEntity(); int i = 0; foreach (object item in sources) { object newItem = CovertEntityId(item, feed.Entries[i].Entry, entityTypeReference, readContext); i++; yield return(newItem); } }
public void ClrBasedCollectionsAreNullableByDefault() { IEdmModel model = StaticModel.BuildModel(); var indexType = (IEdmEntityType)model.FindDeclaredType(typeof(Index).FullName); IEdmProperty fieldsProperty = indexType.FindProperty(nameof(Index.Fields)); Assert.AreEqual(true, fieldsProperty.Type.IsCollection()); IEdmCollectionTypeReference collectionType = fieldsProperty.Type.AsCollection(); Assert.AreEqual(true, collectionType.IsNullable); Assert.AreEqual(true, collectionType.ElementType().IsNullable); }
public ODataFeedSerializer(IEdmCollectionTypeReference edmCollectionType, ODataSerializerProvider serializerProvider) : base(edmCollectionType, ODataPayloadKind.Feed, serializerProvider) { Contract.Assert(edmCollectionType != null); _edmCollectionType = edmCollectionType; if (!edmCollectionType.ElementType().IsEntity()) { throw Error.NotSupported(SRResources.TypeMustBeEntityCollection, edmCollectionType.ElementType().FullName(), typeof(IEdmEntityType).Name); } Contract.Assert(edmCollectionType.ElementType() != null); Contract.Assert(edmCollectionType.ElementType().AsEntity() != null); Contract.Assert(edmCollectionType.ElementType().AsEntity().Definition != null); Contract.Assert(edmCollectionType.ElementType().AsEntity().Definition as IEdmEntityType != null); _edmElementType = _edmCollectionType.ElementType().AsEntity().Definition as IEdmEntityType; }
private ODataCollectionValue ReadCollectionValue(IEdmCollectionTypeReference collectionTypeReference, string payloadTypeName, SerializationTypeNameAnnotation serializationTypeNameAnnotation) { this.IncreaseRecursionDepth(); ODataCollectionValue value2 = new ODataCollectionValue { TypeName = (collectionTypeReference == null) ? payloadTypeName : collectionTypeReference.ODataFullName() }; if (serializationTypeNameAnnotation != null) { value2.SetAnnotation<SerializationTypeNameAnnotation>(serializationTypeNameAnnotation); } base.XmlReader.MoveToElement(); List<object> sourceEnumerable = new List<object>(); if (!base.XmlReader.IsEmptyElement) { base.XmlReader.ReadStartElement(); IEdmTypeReference expectedTypeReference = (collectionTypeReference == null) ? null : collectionTypeReference.ElementType(); DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = base.CreateDuplicatePropertyNamesChecker(); CollectionWithoutExpectedTypeValidator collectionValidator = null; if (collectionTypeReference == null) { string itemTypeNameFromCollection = (payloadTypeName == null) ? null : EdmLibraryExtensions.GetCollectionItemTypeName(payloadTypeName); collectionValidator = new CollectionWithoutExpectedTypeValidator(itemTypeNameFromCollection); } do { switch (base.XmlReader.NodeType) { case XmlNodeType.Element: if (base.XmlReader.NamespaceEquals(base.XmlReader.ODataNamespace)) { if (!base.XmlReader.LocalNameEquals(this.ODataCollectionItemElementName)) { throw new ODataException(Microsoft.Data.OData.Strings.ODataAtomPropertyAndValueDeserializer_InvalidCollectionElement(base.XmlReader.LocalName, base.XmlReader.ODataNamespace)); } object item = this.ReadNonEntityValueImplementation(expectedTypeReference, duplicatePropertyNamesChecker, collectionValidator, true, false); base.XmlReader.Read(); ValidationUtils.ValidateCollectionItem(item, false); sourceEnumerable.Add(item); } else { base.XmlReader.Skip(); } break; case XmlNodeType.EndElement: break; default: base.XmlReader.Skip(); break; } } while (base.XmlReader.NodeType != XmlNodeType.EndElement); } value2.Items = new ReadOnlyEnumerable(sourceEnumerable); this.DecreaseRecursionDepth(); return value2; }
internal static IEnumerable CovertFeedIds(IEnumerable sources, ODataFeedWithEntries feed, IEdmCollectionTypeReference collectionType, ODataDeserializerContext readContext) { IEdmEntityTypeReference entityTypeReference = collectionType.ElementType().AsEntity(); int i = 0; foreach (object item in sources) { object newItem = CovertEntityId(item, feed.Entries[i].Entry, entityTypeReference, readContext); i++; yield return newItem; } }
/// <summary> /// Initializes a new instance of the <see cref="ODataCollectionDeserializer"/> class. /// </summary> /// <param name="edmType">The collection type that this deserializer can read.</param> /// <param name="deserializerProvider">The deserializer provider to use to read inner objects.</param> public ODataCollectionDeserializer(IEdmCollectionTypeReference edmType, ODataDeserializerProvider deserializerProvider) : base(edmType, ODataPayloadKind.Collection, deserializerProvider) { CollectionType = edmType; ElementType = edmType.ElementType(); }
/// <summary> /// Read a collection from the reader. /// </summary> /// <param name="collectionTypeReference">The type of the collection to read (or null if no type is available).</param> /// <param name="payloadTypeName">The name of the collection type specified in the payload.</param> /// <param name="serializationTypeNameAnnotation">The serialization type name for the collection value (possibly null).</param> /// <returns>The value read from the payload.</returns> /// <remarks> /// Pre-Condition: XmlNodeType.Element - the element to read the value for. /// XmlNodeType.Attribute - an attribute on the element to read the value for. /// Post-Condition: XmlNodeType.Element - the element was empty. /// XmlNodeType.EndElement - the element had some value. /// /// Note that this method will not read null values, those should be handled by the caller already. /// </remarks> private ODataCollectionValue ReadCollectionValue( IEdmCollectionTypeReference collectionTypeReference, string payloadTypeName, SerializationTypeNameAnnotation serializationTypeNameAnnotation) { this.AssertXmlCondition(XmlNodeType.Element, XmlNodeType.Attribute); Debug.Assert( collectionTypeReference == null || collectionTypeReference.IsNonEntityCollectionType(), "If the metadata is specified it must denote a collection for this method to work."); this.IncreaseRecursionDepth(); ODataCollectionValue collectionValue = new ODataCollectionValue(); // If we have a metadata type for the collection, use that type name // otherwise use the type name from the payload (if there was any). collectionValue.TypeName = collectionTypeReference == null ? payloadTypeName : collectionTypeReference.ODataFullName(); if (serializationTypeNameAnnotation != null) { collectionValue.SetAnnotation(serializationTypeNameAnnotation); } // Move to the element (so that if we were on an attribute we can test the element for being empty) this.XmlReader.MoveToElement(); List<object> items = new List<object>(); // Empty collections are valid - they have no items if (!this.XmlReader.IsEmptyElement) { // Read over the collection element to its first child node (or end-element) this.XmlReader.ReadStartElement(); // If we don't have metadata (that is collectionType is null) we parse the type name // and extract the item type name from it. Then we create a CollectionWithoutExpectedTypeValidator // instance and use it to ensure that all item types read for the collection value are consistent with // the item type derived from the collection value's type name. // Note that if an item does not specify a type name but the collection value does, the item will be // assigned the item type name computed from the collection value's type. // Note that JSON doesn't have this problem since in JSON we always have metadata and thus the collectionType // is never null by the time we get to a similar place in the code. IEdmTypeReference itemTypeReference = collectionTypeReference == null ? null : collectionTypeReference.ElementType(); DuplicatePropertyNamesChecker duplicatePropertyNamesChecker = this.CreateDuplicatePropertyNamesChecker(); CollectionWithoutExpectedTypeValidator collectionValidator = null; if (collectionTypeReference == null) { // Parse the type name from the payload (if any), extract the item type name and construct a collection validator string itemTypeName = payloadTypeName == null ? null : EdmLibraryExtensions.GetCollectionItemTypeName(payloadTypeName); collectionValidator = new CollectionWithoutExpectedTypeValidator(itemTypeName); } do { switch (this.XmlReader.NodeType) { case XmlNodeType.Element: if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataMetadataNamespace)) { if (!this.XmlReader.LocalNameEquals(this.ODataCollectionItemElementName)) { this.XmlReader.Skip(); } else { object itemValue = this.ReadNonEntityValueImplementation( itemTypeReference, duplicatePropertyNamesChecker, collectionValidator, /*validateNullValue*/ true, /*propertyName*/ null); // read over the end tag of the element or the start tag if the element was empty. this.XmlReader.Read(); // Validate the item (for example that it's not null) ValidationUtils.ValidateCollectionItem(itemValue, itemTypeReference.IsNullable()); // Note that the ReadNonEntityValue already validated that the actual type of the value matches // the expected type (the itemType). items.Add(itemValue); } } else if (this.XmlReader.NamespaceEquals(this.XmlReader.ODataNamespace)) { throw new ODataException(ODataErrorStrings.ODataAtomPropertyAndValueDeserializer_InvalidCollectionElement(this.XmlReader.LocalName, this.XmlReader.ODataMetadataNamespace)); } else { this.XmlReader.Skip(); } break; case XmlNodeType.EndElement: // End of the collection. break; default: // Non-element so for example a text node, just ignore this.XmlReader.Skip(); break; } } while (this.XmlReader.NodeType != XmlNodeType.EndElement); } collectionValue.Items = new ReadOnlyEnumerable(items); this.AssertXmlCondition(true, XmlNodeType.EndElement); Debug.Assert(collectionValue != null, "The method should never return null since it doesn't handle null values."); this.DecreaseRecursionDepth(); return collectionValue; }
private object Convert(ODataCollectionReader reader, IEdmCollectionTypeReference collectionType, ODataDeserializerContext readContext) { IEdmTypeReference elementType = collectionType.ElementType(); Type clrElementType = EdmLibHelpers.GetClrType(elementType, readContext.Model); IList list = Activator.CreateInstance(typeof(List<>).MakeGenericType(clrElementType)) as IList; while (reader.Read()) { switch (reader.State) { case ODataCollectionReaderState.Value: object element = Convert(reader.Item, elementType, readContext); list.Add(element); break; default: break; } } return list; }
internal static void SetDynamicCollectionProperty(object resource, string propertyName, object value, IEdmCollectionTypeReference edmPropertyType, IEdmStructuredType structuredType, ODataDeserializerContext readContext, AssembliesResolver assembliesResolver) { Contract.Assert(value != null); Contract.Assert(readContext != null); Contract.Assert(readContext.Model != null); IEnumerable collection = value as IEnumerable; Contract.Assert(collection != null); Type resourceType = resource.GetType(); Type elementType = EdmLibHelpers.GetClrType(edmPropertyType.ElementType(), readContext.Model, assembliesResolver); Type propertyType = typeof(ICollection<>).MakeGenericType(elementType); IEnumerable newCollection; if (CollectionDeserializationHelpers.TryCreateInstance(propertyType, edmPropertyType, elementType, out newCollection)) { collection.AddToCollection(newCollection, elementType, resourceType, propertyName, propertyType, assembliesResolver); SetDynamicProperty(resource, propertyName, newCollection, structuredType, readContext); } }