/// <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);
                }
            }
        }
示例#2
0
        /// <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();
        }
示例#3
0
        /// <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));
        }
示例#4
0
        /// <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));
        }
示例#5
0
        /// <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();
        }
示例#6
0
        /// <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();
            });
        }
示例#7
0
        /// <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);
 }
示例#9
0
        /// <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);
        }