/// <summary>
        /// Asynchronously writes the context URI property and the specified value into the payload.
        /// </summary>
        /// <param name="payloadKind">The ODataPayloadKind for the context URI.</param>
        /// <param name="contextUrlInfoGen">Function to generate contextUrlInfo.</param>
        /// <param name="parentContextUrlInfo">The parent contextUrlInfo.</param>
        /// <param name="propertyName">Property name to write contextUri on.</param>
        /// <returns>A task that represents the asynchronous read operation.
        /// The value of the TResult parameter contains the contextUrlInfo,
        /// if the context URI was successfully written.</returns>
        internal async Task <ODataContextUrlInfo> WriteContextUriPropertyAsync(
            ODataPayloadKind payloadKind,
            Func <ODataContextUrlInfo> contextUrlInfoGen = null,
            ODataContextUrlInfo parentContextUrlInfo     = null,
            string propertyName = null)
        {
            if (this.jsonLightOutputContext.MetadataLevel is JsonNoMetadataLevel)
            {
                return(null);
            }

            ODataContextUrlInfo contextUrlInfo = null;

            if (contextUrlInfoGen != null)
            {
                contextUrlInfo = contextUrlInfoGen();
            }

            if (contextUrlInfo != null && contextUrlInfo.IsHiddenBy(parentContextUrlInfo))
            {
                return(null);
            }

            Uri contextUri = ContextUriBuilder.BuildContextUri(payloadKind, contextUrlInfo);

            if (contextUri != null)
            {
                if (string.IsNullOrEmpty(propertyName))
                {
                    await this.AsynchronousODataAnnotationWriter.WriteInstanceAnnotationNameAsync(ODataAnnotationNames.ODataContext)
                    .ConfigureAwait(false);
                }
                else
                {
                    await this.AsynchronousODataAnnotationWriter.WritePropertyAnnotationNameAsync(propertyName, ODataAnnotationNames.ODataContext)
                    .ConfigureAwait(false);
                }

                await this.AsynchronousJsonWriter.WritePrimitiveValueAsync(contextUri.IsAbsoluteUri?contextUri.AbsoluteUri : contextUri.OriginalString)
                .ConfigureAwait(false);

                this.allowRelativeUri = true;

                return(contextUrlInfo);
            }

            return(null);
        }
示例#2
0
        /// <summary>
        /// Writes the property start element.
        /// </summary>
        /// <param name="beforePropertyCallback">Action called before anything else is written (if it's not null).</param>
        /// <param name="propertyName">The name of the property to write.</param>
        /// <param name="value">The odata value to write.</param>
        /// <param name="isWritingCollection">true if we are writing a collection instead of an entry.</param>
        /// <param name="isTopLevel">true if writing a top-level property payload; otherwise false.</param>
        private void WritePropertyStart(Action beforePropertyCallback, string propertyName, ODataValue value, bool isWritingCollection, bool isTopLevel)
        {
            if (beforePropertyCallback != null)
            {
                beforePropertyCallback();
            }

            if (!isTopLevel)
            {
                // <d:propertyname>
                this.XmlWriter.WriteStartElement(
                    isWritingCollection ? string.Empty : AtomConstants.ODataNamespacePrefix,
                    propertyName,
                    AtomConstants.ODataNamespace);
            }
            else
            {
                // <m:value>
                this.XmlWriter.WriteStartElement(
                    AtomConstants.ODataMetadataNamespacePrefix,
                    AtomConstants.ODataValueElementName,
                    AtomConstants.ODataMetadataNamespace);

                // COMPAT 24: Use standard ('d' and 'm') namespace prefixes for top-level property payloads
                // Top-level collection payloads don't write namespace declarations on the root element (except for the d namespace)
                //             We decided to use the same set of default namespaces on entries, feeds, collections and top-level properties
                DefaultNamespaceFlags namespaces = DefaultNamespaceFlags.Gml | DefaultNamespaceFlags.GeoRss;
                if (!this.MessageWriterSettings.AlwaysUseDefaultXmlNamespaceForRootElement)
                {
                    // DEVNOTE: no need to include the OData namespace here, because we already defined it above.
                    // However, the order will change if we leave it to XmlWriter to add it. So, if the knob hasn't been flipped,
                    // manually add it.
                    namespaces |= DefaultNamespaceFlags.OData;
                }

                this.WriteDefaultNamespaceAttributes(namespaces);

                ODataContextUriBuilder contextUriBuilder = this.AtomOutputContext.CreateContextUriBuilder();

                ODataPayloadKind kind = this.AtomOutputContext.MessageWriterSettings.IsIndividualProperty ? ODataPayloadKind.IndividualProperty : ODataPayloadKind.Property;

                ODataContextUrlInfo contextInfo = ODataContextUrlInfo.Create(value, this.AtomOutputContext.MessageWriterSettings.ODataUri);
                this.WriteContextUriProperty(contextUriBuilder.BuildContextUri(kind, contextInfo));
            }
        }