/// <inheritdoc /> public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { if (messageWriter == null) { throw Error.ArgumentNull("messageWriter"); } if (writeContext == null) { throw Error.ArgumentNull("writeContext"); } if (graph == null) { throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, DeltaFeed)); } IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase; if (entitySet == null) { throw new SerializationException(SRResources.EntitySetMissingDuringSerialization); } IEdmTypeReference feedType = writeContext.GetEdmType(graph, type); Contract.Assert(feedType != null); IEdmEntityTypeReference entityType = GetEntityType(feedType); ODataDeltaWriter writer = messageWriter.CreateODataDeltaWriter(entitySet, entityType.EntityDefinition()); WriteDeltaFeedInline(graph, feedType, writer, writeContext); }
public void GetEdmType_ThrowsInvalidOperation_IfEdmObjectGetEdmTypeReturnsNull() { // Arrange (this code path does not use ODataSerializerContext fields or properties) var context = new ODataSerializerContext(); NullEdmType edmObject = new NullEdmType(); // Act & Assert ExceptionAssert.Throws <InvalidOperationException>(() => context.GetEdmType(edmObject, null), exceptionMessage: "The EDM type of the object of type 'Microsoft.Test.AspNet.OData.Formatter.Serialization.ODataSerializerContextTest+NullEdmType'" + " is null. The EDM type of an IEdmObject cannot be null."); }
public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { // We don't need to check if v3 because output formatter does that for us IEdmTypeReference edmType = writeContext.GetEdmType(graph, type); if (!edmType.IsStructured()) { throw new ArgumentException("type"); } messageWriter.PreemptivelyTranslateResponseStream( edmType, (writer) => base.WriteObject(graph, type, writer, writeContext)); }
public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { if (messageWriter == null) { throw new ArgumentNullException(nameof(messageWriter)); } if (writeContext == null) { throw new ArgumentNullException(nameof(writeContext)); } IEdmTypeReference resourceSetType = writeContext.GetEdmType(graph, type); messageWriter.PreemptivelyTranslateResponseStream( resourceSetType, (writer) => base.WriteObject(graph, type, writer, writeContext)); }
public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { if (messageWriter == null) { throw new ArgumentNullException(nameof(messageWriter)); } if (writeContext == null) { throw new ArgumentNullException(nameof(writeContext)); } IEdmTypeReference collectionType = writeContext.GetEdmType(graph, type); // Translate types in response stream according to expected collection type messageWriter.PreemptivelyTranslateResponseStream( collectionType, (writer) => base.WriteObject(graph, type, writer, writeContext)); }
/// <summary> /// Creates an <see cref="ODataComplexValue"/> for the object represented by <paramref name="graph"/>. /// </summary> /// <param name="graph">The value of the <see cref="ODataComplexValue"/> to be created.</param> /// <param name="complexType">The EDM complex type of the object.</param> /// <param name="writeContext">The serializer context.</param> /// <returns>The created <see cref="ODataComplexValue"/>.</returns> public virtual ODataComplexValue CreateODataComplexValue(object graph, IEdmComplexTypeReference complexType, ODataSerializerContext writeContext) { if (writeContext == null) { throw Error.ArgumentNull("writeContext"); } if (graph == null || graph is NullEdmComplexObject) { return null; } IEdmComplexObject complexObject = graph as IEdmComplexObject ?? new TypedEdmComplexObject(graph, complexType, writeContext.Model); List<ODataProperty> propertyCollection = new List<ODataProperty>(); foreach (IEdmProperty property in complexType.ComplexDefinition().Properties()) { IEdmTypeReference propertyType = property.Type; ODataEdmTypeSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(propertyType); if (propertySerializer == null) { throw Error.NotSupported(SRResources.TypeCannotBeSerialized, propertyType.FullName(), typeof(ODataOutputFormatter).Name); } object propertyValue; if (complexObject.TryGetPropertyValue(property.Name, out propertyValue)) { if (propertyType != null && propertyType.IsComplex()) { IEdmTypeReference actualType = writeContext.GetEdmType(propertyValue, propertyValue.GetType()); if (actualType != null && propertyType != actualType) { propertyType = actualType; } } propertyCollection.Add( propertySerializer.CreateProperty(propertyValue, propertyType, property.Name, writeContext)); } } // Try to add the dynamic properties if the complex type is open. if (complexType.ComplexDefinition().IsOpen) { List<ODataProperty> dynamicProperties = AppendDynamicProperties(complexObject, complexType, writeContext, propertyCollection, new string[0]); if (dynamicProperties != null) { propertyCollection.AddRange(dynamicProperties); } } string typeName = complexType.FullName(); ODataComplexValue value = new ODataComplexValue() { Properties = propertyCollection, TypeName = typeName }; AddTypeNameAnnotationAsNeeded(value, writeContext.MetadataLevel); return value; }
/// <inheritdoc/> public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { if (messageWriter == null) { throw Error.ArgumentNull("messageWriter"); } if (writeContext == null) { throw Error.ArgumentNull("writeContext"); } if (writeContext.RootElementName == null) { throw Error.Argument("writeContext", SRResources.RootElementNameMissing, typeof(ODataSerializerContext).Name); } IEdmTypeReference edmType = writeContext.GetEdmType(graph, type); Contract.Assert(edmType != null); ODataProperty property = CreateProperty(graph, edmType, writeContext.RootElementName, writeContext); messageWriter.WriteProperty(property); }
/// <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"); } var valueCollection = new List<object>(); if (enumerable != null) { ODataEdmTypeSerializer itemSerializer = null; foreach (object item in enumerable) { if (item == null) { if (elementType.IsNullable) { valueCollection.Add(null); continue; } throw new SerializationException(SRResources.NullElementInCollection); } IEdmTypeReference actualType = writeContext.GetEdmType(item, item.GetType()); Contract.Assert(actualType != null); itemSerializer = itemSerializer ?? SerializerProvider.GetEdmTypeSerializer(actualType); if (itemSerializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeSerialized, actualType.FullName(), typeof(ODataOutputFormatter).Name)); } // ODataCollectionWriter expects the individual elements in the collection to be the underlying // values and not ODataValues. valueCollection.Add( itemSerializer.CreateODataValue(item, actualType, 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; }
/// <inheritdoc/> public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { if (messageWriter == null) { throw Error.ArgumentNull("messageWriter"); } if (writeContext == null) { throw Error.ArgumentNull("writeContext"); } IEdmTypeReference collectionType = writeContext.GetEdmType(graph, type); Contract.Assert(collectionType != null); IEdmTypeReference elementType = GetElementType(collectionType); ODataCollectionWriter writer = messageWriter.CreateODataCollectionWriter(elementType); WriteCollection(writer, graph, collectionType.AsCollection(), writeContext); }
private IEdmEntityTypeReference GetEntityType(object graph, ODataSerializerContext writeContext) { Contract.Assert(graph != null); IEdmTypeReference edmType = writeContext.GetEdmType(graph, graph.GetType()); Contract.Assert(edmType != null); if (!edmType.IsEntity()) { throw new SerializationException( Error.Format(SRResources.CannotWriteType, GetType().Name, edmType.FullName())); } return edmType.AsEntity(); }