/// <summary> /// Writes a collection item (either primitive or complex) /// </summary> /// <param name="item">The collection item to write.</param> protected override void WriteItemImplementation(object item) { if (item == null) { this.jsonWriter.WriteValue(null); } else { ODataComplexValue complexValue = item as ODataComplexValue; if (complexValue != null) { ODataJsonWriterUtils.WriteComplexValue(this.jsonWriter, this.MetadataProvider, complexValue, null, false, this.Version); } else { ODataMultiValue multiValue = item as ODataMultiValue; if (multiValue != null) { throw new ODataException(Strings.ODataCollectionWriter_MultiValuesNotSupportedInCollections); } ODataJsonWriterUtils.WritePrimitiveValue(this.jsonWriter, item, null); } } }
/// <summary> /// Start writing a regular (non-expanded) link. /// </summary> /// <param name="link">The link to write.</param> protected override void WriteLink(ODataLink link) { Debug.Assert(link != null, "link != null"); ValidationUtils.ValidateLink(link); // Link must specify the Url for non-expanded links // NOTE: we currently only require a non-null Url for ATOM payloads and non-expanded links in JSON. // There is no place in JSON to write a Url if the link is expanded. We can't change that for v1 and v2; we // might fix the protocol for v3. if (link.Url == null) { throw new ODataException(Strings.ODataWriter_LinkMustSpecifyUrl); } Debug.Assert(!string.IsNullOrEmpty(link.Name), "The link Name should have been validated by now."); this.jsonWriter.WriteName(link.Name); // A deferred link is represented as an object this.jsonWriter.StartObjectScope(); // "__deferred": { this.jsonWriter.WriteName(JsonConstants.ODataDeferredName); this.jsonWriter.StartObjectScope(); Debug.Assert(link.Url != null, "The link Url should have been validated by now."); this.jsonWriter.WriteName(JsonConstants.ODataLinkUriName); this.jsonWriter.WriteValue(ODataJsonWriterUtils.UriToAbsoluteUriString(link.Url, this.BaseUri)); // End the __deferred object this.jsonWriter.EndObjectScope(); // End the link value this.jsonWriter.EndObjectScope(); }
/// <summary> /// Writes a set of links (Uris) in response to a $links query; includes optional count and next-page-link information. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="baseUri">The base Uri used for writing.</param> /// <param name="associatedEntityLinks">The set of associated entity links to write out.</param> /// <param name="version">The protocol version used for writing.</param> /// <param name="writingResponse">Flag indicating whether a request or a response is being written.</param> internal static void WriteAssociatedEntityLinks(JsonWriter jsonWriter, Uri baseUri, ODataAssociatedEntityLinks associatedEntityLinks, ODataVersion version, bool writingResponse) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(associatedEntityLinks != null, "associatedEntityLinks != null"); ODataJsonWriterUtils.WriteDataWrapper( jsonWriter, writingResponse, () => WriteAssociatedEntityLinks(jsonWriter, baseUri, associatedEntityLinks, version >= ODataVersion.V2 && writingResponse)); }
/// <summary> /// Writes a single top-level Uri in response to a $links query. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="baseUri">The base Uri used for writing.</param> /// <param name="link">The associated entity link to write out.</param> /// <param name="writingResponse">Flag indicating whether a request or a response is being written.</param> internal static void WriteAssociatedEntityLink(JsonWriter jsonWriter, Uri baseUri, ODataAssociatedEntityLink link, bool writingResponse) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(link != null, "link != null"); ODataJsonWriterUtils.WriteDataWrapper( jsonWriter, writingResponse, () => WriteAssociatedEntityLink(jsonWriter, baseUri, link)); }
/// <summary> /// Finish writing an entry. /// </summary> /// <param name="entry">The entry to write.</param> protected override void EndEntry(ODataEntry entry) { Debug.Assert(entry != null, "entry != null"); // Write the metadata ResourceType entryType = this.WriteEntryMetadata(entry); // named streams // TODO: implement support for named streams if (entry.NamedStreams != null) { } // Write the properties ODataJsonWriterUtils.WriteProperties(this.jsonWriter, this.MetadataProvider, entryType, entry.Properties, this.Version); // Close the object scope this.jsonWriter.EndObjectScope(); }
/// <summary> /// Write an <see cref="ODataProperty" /> to the given stream. This method creates an /// async buffered stream and writes the property to it. /// </summary> /// <param name="jsonWriter">The <see cref="JsonWriter"/> to write to.</param> /// <param name="metadata">The metadata provider to use or null if no metadata is available.</param> /// <param name="property">The property to write.</param> /// <param name="owningType">The type owning the property (or null if no metadata is available).</param> /// <param name="version">The protocol version used for writing.</param> /// <param name="writingResponse">Flag indicating whether a request or a response is being written.</param> internal static void WriteTopLevelProperty( JsonWriter jsonWriter, DataServiceMetadataProviderWrapper metadata, ODataProperty property, ResourceType owningType, ODataVersion version, bool writingResponse) { DebugUtils.CheckNoExternalCallers(); Debug.Assert(jsonWriter != null, "jsonWriter != null"); Debug.Assert(property != null, "property != null"); ODataJsonWriterUtils.WriteDataWrapper( jsonWriter, writingResponse, () => { jsonWriter.StartObjectScope(); WriteProperty(jsonWriter, metadata, property, owningType, version); jsonWriter.EndObjectScope(); }); }
/// <summary> /// Finish writing a feed. /// </summary> /// <param name="feed">The feed to write.</param> protected override void EndFeed(ODataFeed feed) { Debug.Assert(feed != null, "feed != null"); // End the array which holds the entries in the feed. this.jsonWriter.EndArrayScope(); // We need to close the "results" wrapper for V2 and higher and only for responses Uri nextPageLink = feed.NextPageLink; if (this.Version >= ODataVersion.V2 && (this.WritingResponse || !this.IsTopLevel)) { // "__next": "url" if (nextPageLink != null) { this.jsonWriter.WriteName(JsonConstants.ODataNextLinkName); this.jsonWriter.WriteValue(ODataJsonWriterUtils.UriToAbsoluteUriString(nextPageLink, this.BaseUri)); } this.jsonWriter.EndObjectScope(); } }
/// <summary> /// Write an error message. /// </summary> /// <param name='error'>The error to write.</param> /// <param name="includeDebugInformation">If in debug mode error details will be included (if present).</param> protected override void SerializeError(ODataError error, bool includeDebugInformation) { Debug.Assert(error != null, "error != null"); ODataJsonWriterUtils.WriteError(this.jsonWriter, error, includeDebugInformation); }
/// <summary> /// Writes the __metadata property and its content for an entry /// </summary> /// <param name="entry">The entry for which to write the metadata.</param> /// <returns>The resource type of the entry or null if no metadata is available.</returns> private ResourceType WriteEntryMetadata(ODataEntry entry) { Debug.Assert(entry != null, "entry != null"); // Write the "__metadata" for the entry this.jsonWriter.WriteName(JsonConstants.ODataMetadataName); this.jsonWriter.StartObjectScope(); // Write the "uri": "edit/read-link-uri" Uri uriValue = entry.EditLink; if (uriValue == null) { uriValue = entry.ReadLink; } if (uriValue != null) { this.jsonWriter.WriteName(JsonConstants.ODataMetadataUriName); this.jsonWriter.WriteValue(ODataJsonWriterUtils.UriToAbsoluteUriString(uriValue, this.BaseUri)); } // Write the "etag": "ETag value" // TODO: if this is a top-level entry also put the ETag into the headers. string etag = entry.ETag; if (etag != null) { this.jsonWriter.WriteName(JsonConstants.ODataMetadataETagName); this.jsonWriter.WriteValue(etag); } // Write the "type": "typename" string typeName = entry.TypeName; ResourceType entryType = ValidationUtils.ValidateTypeName(this.MetadataProvider, typeName, ResourceTypeKind.EntityType, false); if (typeName != null) { this.jsonWriter.WriteName(JsonConstants.ODataMetadataTypeName); this.jsonWriter.WriteValue(typeName); } // Write MLE metadata ODataMediaResource mediaResource = entry.MediaResource; if (mediaResource != null) { // Write the "edit_media": "url" Uri mediaEditLink = mediaResource.EditLink; if (mediaEditLink != null) { this.jsonWriter.WriteName(JsonConstants.ODataMetadataEditMediaName); this.jsonWriter.WriteValue(ODataJsonWriterUtils.UriToAbsoluteUriString(mediaEditLink, this.BaseUri)); } // Write the "media_src": "url" Debug.Assert(mediaResource.ReadLink != null, "The default stream read link should have been validated by now."); this.jsonWriter.WriteName(JsonConstants.ODataMetadataMediaUriName); this.jsonWriter.WriteValue(ODataJsonWriterUtils.UriToAbsoluteUriString(mediaResource.ReadLink, this.BaseUri)); // Write the "content_type": "type" Debug.Assert(!string.IsNullOrEmpty(mediaResource.ContentType), "The default stream content type should have been validated by now."); this.jsonWriter.WriteName(JsonConstants.ODataMetadataContentTypeName); this.jsonWriter.WriteValue(mediaResource.ContentType); // Write the "media_etag": "etag" string mediaETag = mediaResource.ETag; if (mediaETag != null) { Debug.Assert(mediaEditLink != null, "The default stream edit link and etag should have been validated by now."); this.jsonWriter.WriteName(JsonConstants.ODataMetadataMediaETagName); this.jsonWriter.WriteValue(mediaETag); } } // Write properties metadata // For now only association links are supported here IEnumerable <ODataAssociationLink> associationLinks = entry.AssociationLinks; if (associationLinks != null) { bool firstAssociationLink = true; foreach (ODataAssociationLink associationLink in associationLinks) { ValidationUtils.ValidateAssociationLink(associationLink, this.Version); if (firstAssociationLink) { // Write the "properties": { this.jsonWriter.WriteName(JsonConstants.ODataMetadataPropertiesName); this.jsonWriter.StartObjectScope(); firstAssociationLink = false; } // Write the "LinkName": { this.jsonWriter.WriteName(associationLink.Name); this.jsonWriter.StartObjectScope(); // Write the "__associationuri": "url" this.jsonWriter.WriteName(JsonConstants.ODataMetadataPropertiesAssociationUriName); this.jsonWriter.WriteValue(ODataJsonWriterUtils.UriToAbsoluteUriString(associationLink.Url, this.BaseUri)); // Close the "LinkName" object this.jsonWriter.EndObjectScope(); } if (!firstAssociationLink) { // Close the "properties" object this.jsonWriter.EndObjectScope(); } } // Close the __metadata object scope this.jsonWriter.EndObjectScope(); return(entryType); }