Esempio n. 1
0
        /// <summary>
        /// Read the start of the top-level data wrapper in JSON responses.
        /// </summary>
        /// <param name="payloadKind">The kind of payload we are reading; this guides the parsing of the metadata URI.</param>
        /// <param name="duplicatePropertyNamesChecker">The duplicate property names checker.</param>
        /// <param name="isReadingNestedPayload">true if we are deserializing a nested payload, e.g. an entry, a feed or a collection within a parameters payload.</param>
        /// <param name="allowEmptyPayload">true if we allow a comletely empty payload; otherwise false.</param>
        /// <returns>The parsed metadata URI.</returns>
        /// <remarks>
        /// Pre-Condition:  JsonNodeType.None:      assumes that the JSON reader has not been used yet when not reading a nested payload.
        /// Post-Condition: The reader is positioned on the first property of the payload after having read (or skipped) the metadata URI property.
        ///                 Or the reader is positioned on an end-object node if there are no properties (other than the metadata URI which is required in responses and optional in requests).
        /// </remarks>
        internal Task ReadPayloadStartAsync(
            ODataPayloadKind payloadKind,
            DuplicatePropertyNamesChecker duplicatePropertyNamesChecker,
            bool isReadingNestedPayload,
            bool allowEmptyPayload)
        {
            DebugUtils.CheckNoExternalCallers();
            this.JsonReader.AssertNotBuffering();
            Debug.Assert(isReadingNestedPayload || this.JsonReader.NodeType == JsonNodeType.None, "Pre-Condition: JSON reader must not have been used yet when not reading a nested payload.");

            return(TaskUtils.GetTaskForSynchronousOperation(() =>
            {
                string metadataUriAnnotationValue = this.ReadPayloadStartImplementation(
                    payloadKind,
                    duplicatePropertyNamesChecker,
                    isReadingNestedPayload,
                    allowEmptyPayload);

                // The metadata URI is only recognized in non-error response top-level payloads.
                // If the payload is nested (for example when we read URL literals) we don't recognize the metadata URI.
                // Top-level error payloads don't need and use the metadata URI.
                if (!isReadingNestedPayload && payloadKind != ODataPayloadKind.Error)
                {
                    this.metadataUriParseResult = this.jsonLightInputContext.PayloadKindDetectionState == null
                            ? null
                            : this.jsonLightInputContext.PayloadKindDetectionState.MetadataUriParseResult;
                    if (this.metadataUriParseResult == null && metadataUriAnnotationValue != null)
                    {
                        this.metadataUriParseResult = ODataJsonLightMetadataUriParser.Parse(
                            this.Model,
                            metadataUriAnnotationValue,
                            payloadKind,
                            this.Version,
                            this.MessageReaderSettings.ReaderBehavior);
                    }
                }

#if DEBUG
                this.metadataUriParseResultReady = true;
#endif
            }));
        }
        /// <summary>
        /// Creates a metadata URI parser and parses the metadata URI read from the payload.
        /// </summary>
        /// <param name="model">The model to use when resolving the target of the URI.</param>
        /// <param name="metadataUriFromPayload">The string value of the odata.metadata annotation read from the payload.</param>
        /// <param name="payloadKind">The payload kind we expect the metadata URI to conform to.</param>
        /// <param name="version">The OData version to use for determining the set of built-in functions available.</param>
        /// <param name="readerBehavior">Reader behavior if the caller is a reader, null if no reader behavior is available.</param>
        /// <returns>The result from parsing the metadata URI.</returns>
        internal static ODataJsonLightMetadataUriParseResult Parse(
            IEdmModel model,
            string metadataUriFromPayload,
            ODataPayloadKind payloadKind,
            ODataVersion version,
            ODataReaderBehavior readerBehavior)
        {
            DebugUtils.CheckNoExternalCallers();

            if (metadataUriFromPayload == null)
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightMetadataUriParser_NullMetadataDocumentUri);
            }

            // Create an absolute URI from the payload string
            Uri metadataUri = new Uri(metadataUriFromPayload, UriKind.Absolute);
            ODataJsonLightMetadataUriParser parser = new ODataJsonLightMetadataUriParser(model, metadataUri);

            parser.TokenizeMetadataUri();

            parser.ParseMetadataUri(payloadKind, readerBehavior, version);
            return(parser.parseResult);
        }