/// <inheritdoc/> public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { if (graph == null) { throw Error.ArgumentNull("graph"); } if (messageWriter == null) { throw Error.ArgumentNull("messageWriter"); } ODataError oDataError = graph as ODataError; if (oDataError == null) { HttpError httpError = graph as HttpError; if (httpError == null) { string message = Error.Format(SRResources.ErrorTypeMustBeODataErrorOrHttpError, graph.GetType().FullName); throw new SerializationException(message); } else { oDataError = httpError.CreateODataError(); } } bool includeDebugInformation = oDataError.InnerError != null; messageWriter.WriteError(oDataError, includeDebugInformation); }
/// <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"); } 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); ODataWriter writer = messageWriter.CreateODataFeedWriter(entitySet, entityType.EntityDefinition()); WriteObjectInline(graph, feedType, writer, writeContext); }
/// <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) { ODataEntityReferenceLink entityReferenceLink = graph as ODataEntityReferenceLink; if (entityReferenceLink == null) { Uri uri = graph as Uri; if (uri == null) { throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName)); } entityReferenceLink = new ODataEntityReferenceLink { Url = uri }; } messageWriter.WriteEntityReferenceLink(entityReferenceLink); } }
/// <summary> /// Creates an <see cref="ODataEnumValue"/> for the object represented by <paramref name="graph"/>. /// </summary> /// <param name="graph">The enum value.</param> /// <param name="enumType">The EDM enum type of the value.</param> /// <param name="writeContext">The serializer write context.</param> /// <returns>The created <see cref="ODataEnumValue"/>.</returns> public virtual ODataEnumValue CreateODataEnumValue(object graph, IEdmEnumTypeReference enumType, ODataSerializerContext writeContext) { if (graph == null) { return null; } string value = null; if (graph.GetType().GetTypeInfo().IsEnum) { value = graph.ToString(); } else { if (graph.GetType() == typeof(EdmEnumObject)) { value = ((EdmEnumObject)graph).Value; } } ODataEnumValue enumValue = new ODataEnumValue(value, enumType.FullName()); ODataMetadataLevel metadataLevel = writeContext != null ? writeContext.MetadataLevel : ODataMetadataLevel.MinimalMetadata; AddTypeNameAnnotationAsNeeded(enumValue, enumType, metadataLevel); return enumValue; }
/// <inheritdoc /> public override void WriteObjectInline(object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext) { if (writer == null) { throw Error.ArgumentNull("writer"); } if (writeContext == null) { throw Error.ArgumentNull("writeContext"); } if (expectedType == null) { throw Error.ArgumentNull("expectedType"); } if (graph == null) { throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, Feed)); } IEnumerable enumerable = graph as IEnumerable; // Data to serialize if (enumerable == null) { throw new SerializationException( Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName)); } WriteFeed(enumerable, expectedType, writer, writeContext); }
internal ODataProperty CreateProperty(object graph, IEdmTypeReference expectedType, string elementName, ODataSerializerContext writeContext) { Contract.Assert(elementName != null); return new ODataProperty { Name = elementName, Value = CreateODataValue(graph, expectedType, writeContext) }; }
private EntityInstanceContext(ODataSerializerContext serializerContext, IEdmEntityTypeReference entityType, IEdmEntityObject edmObject) { if (serializerContext == null) { throw Error.ArgumentNull("serializerContext"); } SerializerContext = serializerContext; EntityType = entityType.EntityDefinition(); EdmObject = edmObject; }
/// <inheritdoc/> /// <remarks>The metadata written is from the model set on the <paramref name="messageWriter"/>. The <paramref name="graph" /> /// is not used.</remarks> public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { if (messageWriter == null) { throw Error.ArgumentNull("messageWriter"); } // NOTE: ODataMessageWriter doesn't have a way to set the IEdmModel. So, there is an underlying assumption here that // the model received by this method and the model passed(from configuration) while building ODataMessageWriter is the same (clr object). messageWriter.WriteMetadataDocument(); }
/// <summary> /// Writes the entity collection results to the response message. /// </summary> /// <param name="graph">The entity collection results.</param> /// <param name="type">The type of the entities.</param> /// <param name="messageWriter">The message writer.</param> /// <param name="writeContext">The writing context.</param> public override void WriteObject( object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { EntityCollectionResult collectionResult = graph as EntityCollectionResult; if (collectionResult != null) { graph = collectionResult.Query; } base.WriteObject(graph, type, messageWriter, writeContext); }
/// <summary> /// Writes the entity result to the response message. /// </summary> /// <param name="graph">The entity result to write.</param> /// <param name="type">The type of the entity.</param> /// <param name="messageWriter">The message writer.</param> /// <param name="writeContext">The writing context.</param> public override void WriteObject( object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { EntityResult entityResult = graph as EntityResult; if (entityResult != null) { graph = entityResult.Result; } base.WriteObject(graph, type, messageWriter, writeContext); }
/// <summary> /// Writes the complex result to the response message. /// </summary> /// <param name="graph">The complex result to write.</param> /// <param name="type">The type of the complex.</param> /// <param name="messageWriter">The message writer.</param> /// <param name="writeContext">The writing context.</param> public override void WriteObject( object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { ComplexResult complexResult = graph as ComplexResult; if (complexResult != null) { graph = complexResult.Result; } base.WriteObject(graph, type, messageWriter, writeContext); }
/// <inheritdoc/> public override sealed ODataValue CreateODataValue(object graph, IEdmTypeReference expectedType, ODataSerializerContext writeContext) { if (!expectedType.IsPrimitive()) { throw Error.InvalidOperation(SRResources.CannotWriteType, typeof(ODataPrimitiveSerializer), expectedType.FullName()); } ODataPrimitiveValue value = CreateODataPrimitiveValue(graph, expectedType.AsPrimitive(), writeContext); if (value == null) { return new ODataNullValue(); } return value; }
/// <inheritdoc/> public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { if (messageWriter == null) { throw Error.ArgumentNull("messageWriter"); } if (graph == null) { throw Error.ArgumentNull("graph"); } ODataServiceDocument serviceDocument = graph as ODataServiceDocument; if (serviceDocument == null) { throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, type.Name)); } messageWriter.WriteServiceDocument(serviceDocument); }
/// <summary> /// Writes the entity result to the response message. /// </summary> /// <param name="graph">The entity result to write.</param> /// <param name="type">The type of the entity.</param> /// <param name="messageWriter">The message writer.</param> /// <param name="writeContext">The writing context.</param> public override void WriteObject( object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { RawResult rawResult = graph as RawResult; if (rawResult != null) { graph = rawResult.Result; } if (writeContext != null) { graph = RestierPrimitiveSerializer.ConvertToPayloadValue(writeContext.Model, graph); } base.WriteObject(graph, type, messageWriter, writeContext); }
/// <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); messageWriter.WriteProperty(CreateProperty(graph, edmType, writeContext.RootElementName, writeContext)); }
/// <inheritdoc/> public override void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { if (messageWriter == null) { throw Error.ArgumentNull("messageWriter"); } if (graph == null) { throw Error.ArgumentNull("graph"); } if (graph.GetType().GetTypeInfo().IsEnum) { messageWriter.WriteValue(graph.ToString()); } else { messageWriter.WriteValue(ODataPrimitiveSerializer.ConvertUnsupportedPrimitives(graph)); } }
/// <inheridoc /> 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) { ODataEntityReferenceLinks entityReferenceLinks = graph as ODataEntityReferenceLinks; if (entityReferenceLinks == null) { IEnumerable<Uri> uris = graph as IEnumerable<Uri>; if (uris == null) { throw new SerializationException(Error.Format(SRResources.CannotWriteType, GetType().Name, graph.GetType().FullName)); } entityReferenceLinks = new ODataEntityReferenceLinks { Links = uris.Select(uri => new ODataEntityReferenceLink { Url = uri }) }; if (writeContext.Request != null) { entityReferenceLinks.Count = writeContext.Request.ODataProperties().TotalCount; } } messageWriter.WriteEntityReferenceLinks(entityReferenceLinks); } }
/// <summary> /// Initializes a new instance of the <see cref="EntityInstanceContext"/> class. /// </summary> public EntityInstanceContext() { SerializerContext = new ODataSerializerContext(); }
/// <summary> /// Initializes a new instance of the <see cref="EntityInstanceContext"/> class. /// </summary> /// <param name="serializerContext">The backing <see cref="ODataSerializerContext"/>.</param> /// <param name="entityType">The EDM entity type of this instance context.</param> /// <param name="entityInstance">The object representing the instance of this context.</param> public EntityInstanceContext(ODataSerializerContext serializerContext, IEdmEntityTypeReference entityType, object entityInstance) : this(serializerContext, entityType, AsEdmEntityObject(entityInstance, entityType, serializerContext.Model)) { }
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(ODataOutputFormatter).Name)); } // save this for later to support JSON odata.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 odata.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 // odata.streaming=true support. if (nextPageLink != null) { feed.NextPageLink = nextPageLink; } writer.WriteEnd(); }
private void WriteResponseBody(OutputFormatterContext context) { HttpRequest request = context.HttpContext.Request; HttpResponse response = context.HttpContext.Response; IEdmModel model = request.ODataProperties().Model; if (model == null) { throw Error.InvalidOperation(SRResources.RequestMustHaveModel); } object value = context.Object; Type type = value.GetType(); ODataSerializer serializer = GetSerializer(type, value, model, new DefaultODataSerializerProvider(), request); IUrlHelper urlHelper = context.HttpContext.UrlHelper(); ODataPath path = request.ODataProperties().Path; IEdmNavigationSource targetNavigationSource = path == null ? null : path.NavigationSource; string preferHeader = RequestPreferenceHelpers.GetRequestPreferHeader(request); string annotationFilter = null; if (!String.IsNullOrEmpty(preferHeader)) { ODataMessageWrapper messageWrapper = new ODataMessageWrapper(response.Body, response.Headers); messageWrapper.SetHeader(RequestPreferenceHelpers.PreferHeaderName, preferHeader); annotationFilter = messageWrapper.PreferHeader().AnnotationFilter; } IODataResponseMessage responseMessage = new ODataMessageWrapper(response.Body, response.Headers); if (annotationFilter != null) { responseMessage.PreferenceAppliedHeader().AnnotationFilter = annotationFilter; } Uri baseAddress = GetBaseAddress(request); ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings(_messageWriterSettings) { PayloadBaseUri = baseAddress, Version = ODataProperties.DefaultODataVersion, }; string metadataLink = urlHelper.CreateODataLink(new MetadataPathSegment()); if (metadataLink == null) { throw new SerializationException(SRResources.UnableToDetermineMetadataUrl); } writerSettings.ODataUri = new ODataUri { ServiceRoot = baseAddress, // TODO: 1604 Convert webapi.odata's ODataPath to ODL's ODataPath, or use ODL's ODataPath. SelectAndExpand = request.ODataProperties().SelectExpandClause, Path = (path == null || IsOperationPath(path)) ? null : path.ODLPath, }; using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, writerSettings, model)) { ODataSerializerContext writeContext = new ODataSerializerContext() { Request = request, RequestContext = request.HttpContext, Url = urlHelper, NavigationSource = targetNavigationSource, Model = model, RootElementName = GetRootElementName(path) ?? "root", SkipExpensiveAvailabilityChecks = serializer.ODataPayloadKind == ODataPayloadKind.Feed, Path = path, MetadataLevel = ODataMediaTypes.GetMetadataLevel(context.SelectedContentType), SelectExpandClause = request.ODataProperties().SelectExpandClause }; serializer.WriteObject(value, type, messageWriter, writeContext); } }
/// <inheritdoc/> public sealed override ODataValue CreateODataValue(object graph, IEdmTypeReference expectedType, ODataSerializerContext writeContext) { if (!expectedType.IsEnum()) { throw Error.InvalidOperation(SRResources.CannotWriteType, typeof(ODataEnumSerializer).Name, expectedType.FullName()); } ODataEnumValue value = CreateODataEnumValue(graph, expectedType.AsEnum(), writeContext); if (value == null) { return(new ODataNullValue()); } return(value); }
private void WriteResourceSet(IEnumerable enumerable, IEdmTypeReference resourceSetType, ODataWriter writer, ODataSerializerContext writeContext) { Contract.Assert(writer != null); Contract.Assert(writeContext != null); Contract.Assert(enumerable != null); Contract.Assert(resourceSetType != null); IEdmStructuredTypeReference elementType = GetResourceType(resourceSetType); ODataResourceSet resourceSet = CreateResourceSet(enumerable, resourceSetType.AsCollection(), writeContext); if (resourceSet == null) { throw new SerializationException(Error.Format(SRResources.CannotSerializerNull, ResourceSet)); } IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase; if (entitySet == null) { resourceSet.SetSerializationInfo(new ODataResourceSerializationInfo { IsFromCollection = true, NavigationSourceEntityTypeName = elementType.FullName(), NavigationSourceKind = EdmNavigationSourceKind.UnknownEntitySet, NavigationSourceName = null }); } ODataEdmTypeSerializer resourceSerializer = SerializerProvider.GetEdmTypeSerializer(elementType); if (resourceSerializer == null) { throw new SerializationException( Error.Format(SRResources.TypeCannotBeSerialized, elementType.FullName())); } // save this for later to support JSON odata.streaming. Uri nextPageLink = resourceSet.NextPageLink; resourceSet.NextPageLink = null; writer.WriteStart(resourceSet); foreach (object item in enumerable) { if (item == null || item is NullEdmComplexObject) { if (elementType.IsEntity()) { throw new SerializationException(SRResources.NullElementInCollection); } // for null complex element, it can be serialized as "null" in the collection. writer.WriteStart(resource: null); writer.WriteEnd(); } else { resourceSerializer.WriteObjectInline(item, elementType, writer, writeContext); } } // Subtle and surprising behavior: If the NextPageLink property is set before calling WriteStart(resourceSet), // the next page link will be written early in a manner not compatible with odata.streaming=true. Instead, if // the next page link is not set when calling WriteStart(resourceSet) but is instead set later on that resourceSet // object before calling WriteEnd(), the next page link will be written at the end, as required for // odata.streaming=true support. if (nextPageLink != null) { resourceSet.NextPageLink = nextPageLink; } writer.WriteEnd(); }
public virtual ODataOperation CreateODataOperation(IEdmOperation operation, ResourceSetContext resourceSetContext, ODataSerializerContext writeContext) { if (operation == null) { throw Error.ArgumentNull("operation"); } if (resourceSetContext == null) { throw Error.ArgumentNull("resourceSetContext"); } if (writeContext == null) { throw Error.ArgumentNull("writeContext"); } ODataMetadataLevel metadataLevel = writeContext.MetadataLevel; IEdmModel model = writeContext.Model; if (metadataLevel != ODataMetadataLevel.FullMetadata) { return(null); } OperationLinkBuilder builder; builder = model.GetOperationLinkBuilder(operation); if (builder == null) { return(null); } Uri target = builder.BuildLink(resourceSetContext); if (target == null) { return(null); } Uri baseUri = new Uri(writeContext.InternalUrlHelper.CreateODataLink(MetadataSegment.Instance)); Uri metadata = new Uri(baseUri, "#" + operation.FullName()); ODataOperation odataOperation; IEdmAction action = operation as IEdmAction; if (action != null) { odataOperation = new ODataAction(); } else { odataOperation = new ODataFunction(); } odataOperation.Metadata = metadata; // Always omit the title in minimal/no metadata modes. ODataResourceSerializer.EmitTitle(model, operation, odataOperation); // Omit the target in minimal/no metadata modes unless it doesn't follow conventions. if (metadataLevel == ODataMetadataLevel.FullMetadata || !builder.FollowsConventions) { odataOperation.Target = target; } return(odataOperation); }
/// <summary> /// Creates an <see cref="ODataPrimitiveValue"/> for the object represented by <paramref name="graph"/>. /// </summary> /// <param name="graph">The primitive value.</param> /// <param name="primitiveType">The EDM primitive type of the value.</param> /// <param name="writeContext">The serializer write context.</param> /// <returns>The created <see cref="ODataPrimitiveValue"/>.</returns> public virtual ODataPrimitiveValue CreateODataPrimitiveValue(object graph, IEdmPrimitiveTypeReference primitiveType, ODataSerializerContext writeContext) { // TODO: Bug 467598: validate the type of the object being passed in here with the underlying primitive type. return CreatePrimitive(graph, primitiveType, writeContext); }
/// <inheritdoc/> public override Task WriteObjectAsync(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { if (graph == null) { throw Error.ArgumentNull("graph"); } if (messageWriter == null) { throw Error.ArgumentNull("messageWriter"); } ODataError oDataError = GetError(graph); bool includeDebugInformation = oDataError.InnerError != null; return(messageWriter.WriteErrorAsync(oDataError, includeDebugInformation)); }
private IEnumerable <ODataOperation> CreateODataOperations(IEnumerable <IEdmOperation> operations, ResourceSetContext resourceSetContext, ODataSerializerContext writeContext) { Contract.Assert(operations != null); Contract.Assert(resourceSetContext != null); Contract.Assert(writeContext != null); foreach (IEdmOperation operation in operations) { ODataOperation oDataOperation = CreateODataOperation(operation, resourceSetContext, writeContext); if (oDataOperation != null) { yield return(oDataOperation); } } }
/// <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) { if (item == null) { if (elementType.IsNullable) { valueCollection.Add(value: 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())); } // 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.Cast <object>(), 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="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); }
internal static ODataPrimitiveValue CreatePrimitive(object value, IEdmPrimitiveTypeReference primitveType, ODataSerializerContext writeContext) { if (value == null) { return null; } object supportedValue = ConvertUnsupportedPrimitives(value); ODataPrimitiveValue primitive = new ODataPrimitiveValue(supportedValue); if (writeContext != null) { AddTypeNameAnnotationAsNeeded(primitive, primitveType, writeContext.MetadataLevel); } return primitive; }
/// <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"); } IEdmEntitySetBase entitySet = writeContext.NavigationSource as IEdmEntitySetBase; IEdmTypeReference resourceSetType = writeContext.GetEdmType(graph, type); Contract.Assert(resourceSetType != null); IEdmStructuredTypeReference resourceType = GetResourceType(resourceSetType); ODataWriter writer = messageWriter.CreateODataResourceSetWriter(entitySet, resourceType.StructuredDefinition()); WriteObjectInline(graph, resourceSetType, writer, writeContext); }
/// <summary> /// Writes the given object specified by the parameter graph as a part of an existing OData message using the given /// messageWriter and the writeContext. /// </summary> /// <param name="graph">The object to be written.</param> /// <param name="expectedType">The expected EDM type of the object represented by <paramref name="graph"/>.</param> /// <param name="writer">The <see cref="ODataWriter" /> to be used for writing.</param> /// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param> public virtual void WriteObjectInline(object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext) { throw Error.NotSupported(SRResources.WriteObjectInlineNotSupported, GetType().Name); }
/// <inheritdoc/> public override Task WriteObjectAsync(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) { ODataEntityReferenceLink entityReferenceLink = GetEntityReferenceLink(graph); return(messageWriter.WriteEntityReferenceLinkAsync(entityReferenceLink)); } return(TaskHelpers.Completed()); }
/// <summary> /// Create the <see cref="ODataFeed"/> to be written for the given feed instance. /// </summary> /// <param name="feedInstance">The instance representing the feed being written.</param> /// <param name="feedType">The EDM type of the feed being written.</param> /// <param name="writeContext">The serializer context.</param> /// <returns>The created <see cref="ODataFeed"/> object.</returns> public virtual ODataFeed CreateODataFeed(IEnumerable feedInstance, IEdmCollectionTypeReference feedType, ODataSerializerContext writeContext) { ODataFeed feed = new ODataFeed(); if (writeContext.ExpandedEntity == null) { // If we have more OData format specific information apply it now, only if we are the root feed. PageResult odataFeedAnnotations = feedInstance as PageResult; if (odataFeedAnnotations != null) { feed.Count = odataFeedAnnotations.Count; feed.NextPageLink = odataFeedAnnotations.NextPageLink; } else if (writeContext.Request != null) { feed.NextPageLink = writeContext.Request.ODataProperties().NextLink; long? countValue = writeContext.Request.ODataProperties().TotalCount; if (countValue.HasValue) { feed.Count = countValue.Value; } } } else { // nested feed ITruncatedCollection truncatedCollection = feedInstance as ITruncatedCollection; if (truncatedCollection != null && truncatedCollection.IsTruncated) { feed.NextPageLink = GetNestedNextPageLink(writeContext, truncatedCollection.PageSize); } } return feed; }
private static Uri GetNestedNextPageLink(ODataSerializerContext writeContext, int pageSize) { Contract.Assert(writeContext.ExpandedEntity != null); IEdmNavigationSource sourceNavigationSource = writeContext.ExpandedEntity.NavigationSource; NavigationSourceLinkBuilderAnnotation linkBuilder = writeContext.Model.GetNavigationSourceLinkBuilder(sourceNavigationSource); Uri navigationLink = linkBuilder.BuildNavigationLink(writeContext.ExpandedEntity, writeContext.NavigationProperty); if (navigationLink != null) { // return ODataQueryOptions.GetNextPageLink(navigationLink, pageSize); throw new NotImplementedException("ODataQueryOptions"); } return null; }
/// <summary> /// Create the <see cref="ODataResourceSet"/> to be written for the given resourceSet instance. /// </summary> /// <param name="resourceSetInstance">The instance representing the resourceSet being written.</param> /// <param name="resourceSetType">The EDM type of the resourceSet being written.</param> /// <param name="writeContext">The serializer context.</param> /// <returns>The created <see cref="ODataResourceSet"/> object.</returns> public virtual ODataResourceSet CreateResourceSet(IEnumerable resourceSetInstance, IEdmCollectionTypeReference resourceSetType, ODataSerializerContext writeContext) { ODataResourceSet resourceSet = new ODataResourceSet { TypeName = resourceSetType.FullName() }; IEdmStructuredTypeReference structuredType = GetResourceType(resourceSetType).AsStructured(); if (writeContext.NavigationSource != null && structuredType.IsEntity()) { ResourceSetContext resourceSetContext = ResourceSetContext.Create(writeContext, resourceSetInstance); IEdmEntityType entityType = structuredType.AsEntity().EntityDefinition(); var operations = writeContext.Model.GetAvailableOperationsBoundToCollection(entityType); var odataOperations = CreateODataOperations(operations, resourceSetContext, writeContext); foreach (var odataOperation in odataOperations) { ODataAction action = odataOperation as ODataAction; if (action != null) { resourceSet.AddAction(action); } else { resourceSet.AddFunction((ODataFunction)odataOperation); } } } if (writeContext.ExpandedResource == null) { // If we have more OData format specific information apply it now, only if we are the root feed. PageResult odataResourceSetAnnotations = resourceSetInstance as PageResult; if (odataResourceSetAnnotations != null) { resourceSet.Count = odataResourceSetAnnotations.Count; resourceSet.NextPageLink = odataResourceSetAnnotations.NextPageLink; } else if (writeContext.Request != null) { resourceSet.NextPageLink = writeContext.InternalRequest.Context.NextLink; resourceSet.DeltaLink = writeContext.InternalRequest.Context.DeltaLink; long?countValue = writeContext.InternalRequest.Context.TotalCount; if (countValue.HasValue) { resourceSet.Count = countValue.Value; } } } else { // nested resourceSet ITruncatedCollection truncatedCollection = resourceSetInstance as ITruncatedCollection; if (truncatedCollection != null && truncatedCollection.IsTruncated) { resourceSet.NextPageLink = GetNestedNextPageLink(writeContext, truncatedCollection.PageSize); } ICountOptionCollection countOptionCollection = resourceSetInstance as ICountOptionCollection; if (countOptionCollection != null && countOptionCollection.TotalCount != null) { resourceSet.Count = countOptionCollection.TotalCount; } } return(resourceSet); }
/// <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) { ODataEntityReferenceLink entityReferenceLink = GetEntityReferenceLink(graph); messageWriter.WriteEntityReferenceLink(entityReferenceLink); } }
/// <summary> /// Creates an <see cref="ODataValue"/> for the object represented by <paramref name="graph"/>. /// </summary> /// <param name="graph">The value of the <see cref="ODataValue"/> to be created.</param> /// <param name="expectedType">The expected EDM type of the object represented by <paramref name="graph"/>.</param> /// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param> /// <returns>The <see cref="ODataValue"/> created.</returns> public virtual ODataValue CreateODataValue(object graph, IEdmTypeReference expectedType, ODataSerializerContext writeContext) { throw Error.NotSupported(SRResources.CreateODataValueNotSupported, GetType().Name); }
/// <summary> /// Writes the given object specified by the parameter graph as a whole using the given messageWriter and writeContext. /// </summary> /// <param name="graph">The object to be written</param> /// <param name="type">The type of the object to be written.</param> /// <param name="messageWriter">The <see cref="ODataMessageWriter"/> to be used for writing.</param> /// <param name="writeContext">The <see cref="ODataSerializerContext"/>.</param> public virtual void WriteObject(object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext) { throw Error.NotSupported(SRResources.WriteObjectNotSupported, GetType().Name); }
internal List<ODataProperty> AppendDynamicProperties(object source, IEdmStructuredTypeReference structuredType, ODataSerializerContext writeContext, List<ODataProperty> declaredProperties, string[] selectedDynamicProperties) { Contract.Assert(source != null); Contract.Assert(structuredType != null); Contract.Assert(writeContext != null); Contract.Assert(writeContext.Model != null); PropertyInfo dynamicPropertyInfo = EdmLibHelpers.GetDynamicPropertyDictionary( structuredType.StructuredDefinition(), writeContext.Model); IEdmStructuredObject structuredObject = source as IEdmStructuredObject; object value; IDelta delta = source as IDelta; if (delta == null) { if (dynamicPropertyInfo == null || structuredObject == null || !structuredObject.TryGetPropertyValue(dynamicPropertyInfo.Name, out value) || value == null) { return null; } } else { value = ((EdmStructuredObject)structuredObject).TryGetDynamicProperties(); } IDictionary<string, object> dynamicPropertyDictionary = (IDictionary<string, object>)value; // Build a HashSet to store the declared property names. // It is used to make sure the dynamic property name is different from all declared property names. HashSet<string> declaredPropertyNameSet = new HashSet<string>(declaredProperties.Select(p => p.Name)); List<ODataProperty> dynamicProperties = new List<ODataProperty>(); IEnumerable<KeyValuePair<string, object>> dynamicPropertiesToSelect = dynamicPropertyDictionary.Where( x => !selectedDynamicProperties.Any() || selectedDynamicProperties.Contains(x.Key)); foreach (KeyValuePair<string, object> dynamicProperty in dynamicPropertiesToSelect) { if (String.IsNullOrEmpty(dynamicProperty.Key) || dynamicProperty.Value == null) { continue; // skip the null object } if (declaredPropertyNameSet.Contains(dynamicProperty.Key)) { throw Error.InvalidOperation(SRResources.DynamicPropertyNameAlreadyUsedAsDeclaredPropertyName, dynamicProperty.Key, structuredType.FullName()); } IEdmTypeReference edmTypeReference = writeContext.GetEdmType(dynamicProperty.Value, dynamicProperty.Value.GetType()); if (edmTypeReference == null) { throw Error.NotSupported(SRResources.TypeOfDynamicPropertyNotSupported, dynamicProperty.Value.GetType().FullName, dynamicProperty.Key); } ODataEdmTypeSerializer propertySerializer = SerializerProvider.GetEdmTypeSerializer(edmTypeReference); if (propertySerializer == null) { throw Error.NotSupported(SRResources.DynamicPropertyCannotBeSerialized, dynamicProperty.Key, edmTypeReference.FullName()); } dynamicProperties.Add(propertySerializer.CreateProperty( dynamicProperty.Value, edmTypeReference, dynamicProperty.Key, writeContext)); } return dynamicProperties; }