private void WriteExpandedNavigationProperty( KeyValuePair <IEdmNavigationProperty, SelectExpandClause> navigationPropertyToExpand, EntityInstanceContext entityInstanceContext, ODataWriter writer) { Contract.Assert(entityInstanceContext != null); Contract.Assert(writer != null); IEdmNavigationProperty navigationProperty = navigationPropertyToExpand.Key; SelectExpandClause selectExpandClause = navigationPropertyToExpand.Value; object propertyValue = entityInstanceContext.GetPropertyValue(navigationProperty.Name); if (propertyValue != null) { // create the serializer context for the expanded item. ODataSerializerContext nestedWriteContext = new ODataSerializerContext(entityInstanceContext, selectExpandClause, navigationProperty); // write object. ODataEdmTypeSerializer serializer = SerializerProvider.GetEdmTypeSerializer(navigationProperty.Type); if (serializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeSerialized, navigationProperty.Type.ToTraceString(), typeof(ODataMediaTypeFormatter).Name)); } serializer.WriteObjectInline(propertyValue, navigationProperty.Type, writer, nestedWriteContext); } }
/// <summary> /// Creates the <see cref="ODataProperty"/> to be written for the given entity and the structural property. /// </summary> /// <param name="structuralProperty">The EDM structural property being written.</param> /// <param name="entityInstanceContext">The context for the entity instance being written.</param> /// <returns>The <see cref="ODataProperty"/> to write.</returns> public virtual ODataProperty CreateStructuralProperty(IEdmStructuralProperty structuralProperty, EntityInstanceContext entityInstanceContext) { if (structuralProperty == null) { throw Error.ArgumentNull("structuralProperty"); } if (entityInstanceContext == null) { throw Error.ArgumentNull("entityInstanceContext"); } ODataSerializerContext writeContext = entityInstanceContext.SerializerContext; ODataEdmTypeSerializer serializer = SerializerProvider.GetEdmTypeSerializer(structuralProperty.Type); if (serializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeSerialized, structuralProperty.Type.FullName(), typeof(ODataMediaTypeFormatter).Name)); } object propertyValue = entityInstanceContext.GetPropertyValue(structuralProperty.Name); return(serializer.CreateProperty(propertyValue, structuralProperty.Type, structuralProperty.Name, writeContext)); }
/// <summary> /// Sets the <see cref="ODataEdmTypeSerializer"/> for the given <paramref name="edmType"/> in the serializer cache. /// </summary> /// <param name="edmType">The EDM type.</param> /// <param name="serializer">The serializer to use for the given EDM type.</param> public void SetEdmTypeSerializer(IEdmTypeReference edmType, ODataEdmTypeSerializer serializer) { if (edmType == null) { throw Error.ArgumentNull("edmType"); } _serializerCache.AddOrUpdate(edmType, serializer, (t, s) => serializer); }
private void WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer, ODataSerializerContext writeContext) { Contract.Assert(writer != null); Contract.Assert(writeContext != null); Contract.Assert(enumerable != null); Contract.Assert(feedType != null); IEdmEntityTypeReference elementType = GetEntityType(feedType); ODataFeed feed = CreateODataFeed(enumerable, feedType.AsCollection(), writeContext); if (feed == null) { throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, Feed)); } ODataEdmTypeSerializer entrySerializer = SerializerProvider.GetEdmTypeSerializer(elementType); if (entrySerializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName(), typeof(ODataMediaTypeFormatter).Name)); } // save this for later to support JSON lite streaming. Uri nextPageLink = feed.NextPageLink; feed.NextPageLink = null; writer.WriteStart(feed); foreach (object entry in enumerable) { if (entry == null) { throw new SerializationException(SRResources.NullElementInCollection); } entrySerializer.WriteObjectInline(entry, elementType, writer, writeContext); } // Subtle and suprising behavior: If the NextPageLink property is set before calling WriteStart(feed), // the next page link will be written early in a manner not compatible with streaming=true. Instead, if // the next page link is not set when calling WriteStart(feed) but is instead set later on that feed // object before calling WriteEnd(), the next page link will be written at the end, as required for // streaming=true support. if (nextPageLink != null) { feed.NextPageLink = nextPageLink; } writer.WriteEnd(); }
/// <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); }
private void WriteExpandedNavigationProperty( KeyValuePair <IEdmNavigationProperty, SelectExpandClause> navigationPropertyToExpand, EntityInstanceContext entityInstanceContext, ODataWriter writer) { Contract.Assert(entityInstanceContext != null); Contract.Assert(writer != null); IEdmNavigationProperty navigationProperty = navigationPropertyToExpand.Key; SelectExpandClause selectExpandClause = navigationPropertyToExpand.Value; object propertyValue = entityInstanceContext.GetPropertyValue(navigationProperty.Name); if (propertyValue == null) { if (navigationProperty.Type.IsCollection()) { // A navigation property whose Type attribute specifies a collection, the collection always exists, // it may just be empty. // If a collection of entities can be related, it is represented as a JSON array. An empty // collection of entities (one that contains no entities) is represented as an empty JSON array. writer.WriteStart(new ODataFeed()); } else { // If at most one entity can be related, the value is null if no entity is currently related. writer.WriteStart(entry: null); } writer.WriteEnd(); } else { // create the serializer context for the expanded item. ODataSerializerContext nestedWriteContext = new ODataSerializerContext(entityInstanceContext, selectExpandClause, navigationProperty); // write object. ODataEdmTypeSerializer serializer = SerializerProvider.GetEdmTypeSerializer(navigationProperty.Type); if (serializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeSerialized, navigationProperty.Type.ToTraceString(), typeof(ODataMediaTypeFormatter).Name)); } serializer.WriteObjectInline(propertyValue, navigationProperty.Type, writer, nestedWriteContext); } }
/// <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); 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(ODataMediaTypeFormatter).Name); } object propertyValue; if (complexObject.TryGetPropertyValue(property.Name, out propertyValue)) { propertyCollection.Add( propertySerializer.CreateProperty(propertyValue, property.Type, property.Name, writeContext)); } } string typeName = complexType.FullName(); ODataComplexValue value = new ODataComplexValue() { Properties = propertyCollection, TypeName = typeName }; AddTypeNameAnnotationAsNeeded(value, writeContext.MetadataLevel); return(value); }
/// <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="writeContext">The serializer context.</param> /// <returns>The created <see cref="ODataComplexValue"/>.</returns> public virtual ODataComplexValue CreateODataComplexValue(object graph, ODataSerializerContext writeContext) { if (writeContext == null) { throw Error.ArgumentNull("writeContext"); } if (graph == null) { return(null); } List <ODataProperty> propertyCollection = new List <ODataProperty>(); foreach (IEdmProperty property in _edmComplexType.ComplexDefinition().Properties()) { IEdmTypeReference propertyType = property.Type; ODataEdmTypeSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(propertyType); if (propertySerializer == null) { throw Error.NotSupported(SRResources.TypeCannotBeSerialized, propertyType.FullName(), typeof(ODataMediaTypeFormatter).Name); } // TODO 453795: [OData]Cleanup reflection code in the ODataFormatter. object propertyValue = graph.GetType().GetProperty(property.Name).GetValue(graph, index: null); propertyCollection.Add(propertySerializer.CreateProperty(propertyValue, property.Name, writeContext)); } string typeName = _edmComplexType.FullName(); ODataComplexValue value = new ODataComplexValue() { Properties = propertyCollection, TypeName = typeName }; AddTypeNameAnnotationAsNeeded(value, writeContext.MetadataLevel); return(value); }
public ODataPackageDefaultStreamAwareSerializerProvider() { entitySerializer = new ODataPackageDefaultStreamAwareEntityTypeSerializer(this); }
public static ODataSerializerProvider GetMockODataSerializerProvider(ODataEdmTypeSerializer serializer) { Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>(); serializerProvider.Setup(sp => sp.GetEdmTypeSerializer(It.IsAny<IEdmTypeReference>())).Returns(serializer); return serializerProvider.Object; }
public CustomSerializerProvider(Func<DefaultODataSerializerProvider, ODataEdmTypeSerializer> factory) { _entitySerializer = factory(this); }