/// <summary>
        /// Detects the payload kind(s).
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>A task which returns an enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        internal Task <IEnumerable <ODataPayloadKind> > DetectPayloadKindAsync(ODataPayloadKindDetectionInfo detectionInfo)
        {
            Debug.Assert(detectionInfo != null, "detectionInfo != null");
            Debug.Assert(this.ReadingResponse, "Payload kind detection is only supported in responses.");

            // prevent the buffering JSON reader from detecting in-stream errors - we read the error ourselves
            this.JsonReader.DisableInStreamErrorDetection = true;

            return(this.ReadPayloadStartAsync(
                       ODataPayloadKind.Unsupported,
                       /*propertyAndAnnotationCollector*/ null,
                       /*isReadingNestedPayload*/ false,
                       /*allowEmptyPayload*/ false)

                   .FollowOnSuccessWith(t =>
            {
                return this.DetectPayloadKindImplementation(detectionInfo);
            })

                   .FollowOnFaultAndCatchExceptionWith <IEnumerable <ODataPayloadKind>, ODataException>(t =>
            {
                // If we are not able to read the payload in the expected JSON format/structure
                // return no detected payload kind below.
                return Enumerable.Empty <ODataPayloadKind>();
            })

                   .FollowAlwaysWith(t =>
            {
                this.JsonReader.DisableInStreamErrorDetection = false;
            }));
        }
        /// <summary>
        /// Detects the payload kind(s).
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>A task which returns an enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        internal Task<IEnumerable<ODataPayloadKind>> DetectPayloadKindAsync(ODataPayloadKindDetectionInfo detectionInfo)
        {
            Debug.Assert(detectionInfo != null, "detectionInfo != null");
            Debug.Assert(this.ReadingResponse, "Payload kind detection is only supported in responses.");

            // prevent the buffering JSON reader from detecting in-stream errors - we read the error ourselves
            this.JsonReader.DisableInStreamErrorDetection = true;

            return this.ReadPayloadStartAsync(
                ODataPayloadKind.Unsupported,
                /*duplicatePropertyNamesChecker*/null,
                /*isReadingNestedPayload*/false,
                /*allowEmptyPayload*/false)

                .FollowOnSuccessWith(t =>
                    {
                        return this.DetectPayloadKindImplementation(detectionInfo);
                    })

                .FollowOnFaultAndCatchExceptionWith<IEnumerable<ODataPayloadKind>, ODataException>(t =>
                    {
                        // If we are not able to read the payload in the expected JSON format/structure
                        // return no detected payload kind below.
                        return Enumerable.Empty<ODataPayloadKind>();
                    })

                .FollowAlwaysWith(t =>
                    {
                        this.JsonReader.DisableInStreamErrorDetection = false;
                    });
        }
        /// <summary>
        /// Detects the payload kind(s) from the message stream.
        /// </summary>
        /// <param name="messageStream">The message stream to read from for payload kind detection.</param>
        /// <param name="message">The message being read.</param>
        /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        private Task <IEnumerable <ODataPayloadKind> > DetectPayloadKindImplementationAsync(
            Stream messageStream,
            ODataMessage message,
            bool readingResponse,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            ODataJsonLightInputContext jsonLightInputContext = new ODataJsonLightInputContext(
                this,
                messageStream,
                detectionInfo.ContentType,
                detectionInfo.GetEncoding(),
                detectionInfo.MessageReaderSettings,
                ODataVersion.V4,    // NOTE: we don't rely on the version for payload kind detection; taking the latest.
                readingResponse,
                /*synchronous*/ false,
                detectionInfo.Model,
                /*urlResolver*/ null,
                /*payloadKindDetectionState*/ null);

            return(jsonLightInputContext.DetectPayloadKindAsync(detectionInfo)
                   .FollowAlwaysWith(t =>
            {
                jsonLightInputContext.Dispose();
            }));
        }
        /// <summary>
        /// Detects the payload kind(s).
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        internal IEnumerable<ODataPayloadKind> DetectPayloadKind(ODataPayloadKindDetectionInfo detectionInfo)
        {
            Debug.Assert(detectionInfo != null, "detectionInfo != null");
            Debug.Assert(this.ReadingResponse, "Payload kind detection is only supported in responses.");

            // prevent the buffering JSON reader from detecting in-stream errors - we read the error ourselves
            this.JsonReader.DisableInStreamErrorDetection = true;

            try
            {
                this.ReadPayloadStart(
                    ODataPayloadKind.Unsupported,
                    /*duplicatePropertyNamesChecker*/null,
                    /*isReadingNestedPayload*/false,
                    /*allowEmptyPayload*/false);
                return this.DetectPayloadKindImplementation(detectionInfo);
            }
            catch (ODataException)
            {
                // If we are not able to read the payload in the expected JSON format/structure
                // return no detected payload kind below.
                return Enumerable.Empty<ODataPayloadKind>();
            }
            finally
            {
                this.JsonReader.DisableInStreamErrorDetection = false;
            }
        }
        /// <summary>
        /// Detects the payload kind(s).
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        internal IEnumerable <ODataPayloadKind> DetectPayloadKind(ODataPayloadKindDetectionInfo detectionInfo)
        {
            Debug.Assert(detectionInfo != null, "detectionInfo != null");
            Debug.Assert(this.ReadingResponse, "Payload kind detection is only supported in responses.");

            // prevent the buffering JSON reader from detecting in-stream errors - we read the error ourselves
            this.JsonReader.DisableInStreamErrorDetection = true;

            try
            {
                this.ReadPayloadStart(
                    ODataPayloadKind.Unsupported,
                    /*propertyAndAnnotationCollector*/ null,
                    /*isReadingNestedPayload*/ false,
                    /*allowEmptyPayload*/ false);
                return(this.DetectPayloadKindImplementation(detectionInfo));
            }
            catch (ODataException)
            {
                // If we are not able to read the payload in the expected JSON format/structure
                // return no detected payload kind below.
                return(Enumerable.Empty <ODataPayloadKind>());
            }
            finally
            {
                this.JsonReader.DisableInStreamErrorDetection = false;
            }
        }
Example #6
0
        /// <summary>
        /// Detects the payload kind(s) of the payload.
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero or more payload kinds depending on what payload kinds were detected.</returns>
        internal IEnumerable <ODataPayloadKind> DetectPayloadKind(ODataPayloadKindDetectionInfo detectionInfo)
        {
            Debug.Assert(detectionInfo != null, "detectionInfo != null");

            ODataAtomPayloadKindDetectionDeserializer payloadKindDetectionDeserializer = new ODataAtomPayloadKindDetectionDeserializer(this);

            return(payloadKindDetectionDeserializer.DetectPayloadKind(detectionInfo));
        }
        /// <summary>
        /// Detects the payload kind(s) from the message stream.
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>A task which returns an enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        public Task <IEnumerable <ODataPayloadKind> > DetectPayloadKindAsync(ODataPayloadKindDetectionInfo detectionInfo)
        {
            Debug.Assert(detectionInfo != null, "detectionInfo != null");
            this.VerifyCanDetectPayloadKind();

            ODataJsonLightPayloadKindDetectionDeserializer payloadKindDetectionDeserializer = new ODataJsonLightPayloadKindDetectionDeserializer(this);

            return(payloadKindDetectionDeserializer.DetectPayloadKindAsync(detectionInfo));
        }
Example #8
0
        /// <summary>
        /// Detects the payload kind(s) from the message stream.
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>A task which returns an enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        internal Task <IEnumerable <ODataPayloadKind> > DetectPayloadKindAsync(ODataPayloadKindDetectionInfo detectionInfo)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(detectionInfo != null, "detectionInfo != null");
            this.VerifyCanDetectPayloadKind();

            ODataJsonLightPayloadKindDetectionDeserializer payloadKindDetectionDeserializer = new ODataJsonLightPayloadKindDetectionDeserializer(this);

            return(payloadKindDetectionDeserializer.DetectPayloadKindAsync(detectionInfo));
        }
Example #9
0
        /// <summary>
        /// Detects the payload kinds supported by this format for the specified message payload.
        /// </summary>
        /// <param name="requestMessage">The request message with the payload stream.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>The set of <see cref="ODataPayloadKind"/>s that are supported with the specified payload.</returns>
        internal override IEnumerable<ODataPayloadKind> DetectPayloadKind(
            IODataRequestMessage requestMessage,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            DebugUtils.CheckNoExternalCallers();
            ExceptionUtils.CheckArgumentNotNull(requestMessage, "requestMessage");
            ExceptionUtils.CheckArgumentNotNull(detectionInfo, "detectionInfo");

            Stream messageStream = ((ODataMessage)requestMessage).GetStream();
            return this.DetectPayloadKindImplementation(messageStream, /*readingResponse*/ false, /*synchronous*/ true, detectionInfo);
        }
Example #10
0
        /// <summary>
        /// Detects the payload kinds supported by this format for the specified message payload.
        /// </summary>
        /// <param name="requestMessage">The request message with the payload stream.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>The set of <see cref="ODataPayloadKind"/>s that are supported with the specified payload.</returns>
        internal override IEnumerable <ODataPayloadKind> DetectPayloadKind(
            IODataRequestMessage requestMessage,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            ExceptionUtils.CheckArgumentNotNull(requestMessage, "requestMessage");
            ExceptionUtils.CheckArgumentNotNull(detectionInfo, "detectionInfo");

            Stream messageStream = ((ODataMessage)requestMessage).GetStream();

            return(this.DetectPayloadKindImplementation(messageStream, /*readingResponse*/ false, /*synchronous*/ true, detectionInfo));
        }
Example #11
0
        /// <summary>
        /// Detects the payload kind(s) from the message stream.
        /// </summary>
        /// <param name="messageInfo">The context information for the message.</param>
        /// <param name="settings">Configuration settings of the OData reader.</param>
        /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        private static IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(
            ODataMessageInfo messageInfo,
            ODataMessageReaderSettings settings)
        {
            var detectionInfo = new ODataPayloadKindDetectionInfo(messageInfo, settings);

            messageInfo.Encoding = detectionInfo.GetEncoding();
            using (var jsonLightInputContext = new ODataJsonLightInputContext(messageInfo, settings))
            {
                return(jsonLightInputContext.DetectPayloadKind(detectionInfo));
            }
        }
Example #12
0
        /// <summary>
        /// Asynchronously detects the payload kinds supported by this format for the specified message payload.
        /// </summary>
        /// <param name="requestMessage">The request message with the payload stream.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>A task that when completed returns the set of <see cref="ODataPayloadKind"/>s
        /// that are supported with the specified payload.</returns>
        internal override Task <IEnumerable <ODataPayloadKind> > DetectPayloadKindAsync(
            IODataRequestMessageAsync requestMessage,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            ExceptionUtils.CheckArgumentNotNull(requestMessage, "requestMessage");
            ExceptionUtils.CheckArgumentNotNull(detectionInfo, "detectionInfo");

            // NOTE: After getting the message stream we already (asynchronously) buffered the whole stream in memory (in the AsyncBufferedStream).
            //       Until we get Task-based async stream APIs and retire the AsyncBufferedStream, we call the synchronous method on the buffered stream.
            return(((ODataMessage)requestMessage).GetStreamAsync()
                   .FollowOnSuccessWith(streamTask => this.DetectPayloadKindImplementation(streamTask.Result, /*readingResponse*/ false, /*synchronous*/ false, detectionInfo)));
        }
Example #13
0
        /// <summary>
        /// Detects the payload kinds supported by this format for the specified message payload.
        /// </summary>
        /// <param name="requestMessage">The request message with the payload stream.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>The set of <see cref="ODataPayloadKind"/>s that are supported with the specified payload.</returns>
        internal override IEnumerable <ODataPayloadKind> DetectPayloadKind(
            IODataRequestMessage requestMessage,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            DebugUtils.CheckNoExternalCallers();
            ExceptionUtils.CheckArgumentNotNull(requestMessage, "requestMessage");
            ExceptionUtils.CheckArgumentNotNull(detectionInfo, "detectionInfo");

            ODataMessage message       = (ODataMessage)requestMessage;
            Stream       messageStream = message.GetStream();

            return(this.DetectPayloadKindImplementation(messageStream, message, /*readingResponse*/ false, detectionInfo));
        }
Example #14
0
        /// <summary>
        /// Detects the payload kind(s) from the message stream.
        /// </summary>
        /// <param name="messageInfo">The context information for the message.</param>
        /// <param name="settings">Configuration settings of the OData reader.</param>
        /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        private static Task <IEnumerable <ODataPayloadKind> > DetectPayloadKindImplementationAsync(
            ODataMessageInfo messageInfo,
            ODataMessageReaderSettings settings)
        {
            var detectionInfo = new ODataPayloadKindDetectionInfo(messageInfo, settings);

            messageInfo.Encoding = detectionInfo.GetEncoding();
            var jsonLightInputContext = new ODataJsonLightInputContext(messageInfo, settings);

            return(jsonLightInputContext.DetectPayloadKindAsync(detectionInfo)
                   .FollowAlwaysWith(t =>
            {
                jsonLightInputContext.Dispose();
            }));
        }
Example #15
0
 /// <summary>
 /// Detects the payload kind(s) from the message stream.
 /// </summary>
 /// <param name="messageStream">The message stream to read from for payload kind detection.</param>
 /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
 /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
 /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
 private IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(
     Stream messageStream,
     bool readingResponse,
     ODataPayloadKindDetectionInfo detectionInfo)
 {
     using (ODataJsonLightInputContext jsonLightInputContext = new ODataJsonLightInputContext(
                this,
                messageStream,
                detectionInfo.ContentType,
                detectionInfo.GetEncoding(),
                detectionInfo.MessageReaderSettings,
                readingResponse,
                /*synchronous*/ true,
                detectionInfo.Model,
                /*urlResolver*/ null))
     {
         return(jsonLightInputContext.DetectPayloadKind(detectionInfo));
     }
 }
 /// <summary>
 /// Detects the payload kind(s) from the message stream.
 /// </summary>
 /// <param name="messageStream">The message stream to read from for payload kind detection.</param>
 /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
 /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param>
 /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
 /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
 private IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(
     Stream messageStream,
     bool readingResponse,
     bool synchronous,
     ODataPayloadKindDetectionInfo detectionInfo)
 {
     using (ODataJsonInputContext jsonInputContext = new ODataJsonInputContext(
                this,
                messageStream,
                detectionInfo.GetEncoding(),
                detectionInfo.MessageReaderSettings,
                ODataVersion.V3, // NOTE: we don't rely on the version for payload kind detection; taking the latest.
                readingResponse,
                synchronous,
                detectionInfo.Model,
                /*urlResolver*/ null))
     {
         return(jsonInputContext.DetectPayloadKind());
     }
 }
Example #17
0
        /// <summary>
        /// Detects the payload kind(s) from the message stream.
        /// </summary>
        /// <param name="messageStream">The message stream to read from for payload kind detection.</param>
        /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        private Task <IEnumerable <ODataPayloadKind> > DetectPayloadKindImplementationAsync(
            Stream messageStream,
            bool readingResponse,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            ODataJsonLightInputContext jsonLightInputContext = new ODataJsonLightInputContext(
                this,
                messageStream,
                detectionInfo.ContentType,
                detectionInfo.GetEncoding(),
                detectionInfo.MessageReaderSettings,
                readingResponse,
                /*synchronous*/ false,
                detectionInfo.Model,
                /*urlResolver*/ null);

            return(jsonLightInputContext.DetectPayloadKindAsync(detectionInfo)
                   .FollowAlwaysWith(t =>
            {
                jsonLightInputContext.Dispose();
            }));
        }
Example #18
0
        private ODataJsonLightInputContext CreateJsonLightInputContext(
            string payload,
            IEdmModel model,
            bool isAsync    = false,
            bool isResponse = true)
        {
            this.messageInfo = new ODataMessageInfo
            {
                IsResponse = isResponse,
                MediaType  = new ODataMediaType("application", "json", new KeyValuePair <string, string>("odata.streaming", "true")),
                IsAsync    = isAsync,
                Model      = this.model,
            };

            this.messageReaderSettings = new ODataMessageReaderSettings();
            messageReaderSettings.ShouldIncludeAnnotation = ODataUtils.CreateAnnotationFilter("*");
            payloadKindDetectionInfo = new ODataPayloadKindDetectionInfo(this.messageInfo, this.messageReaderSettings);

            return(new ODataJsonLightInputContext(
                       new StringReader(payload),
                       messageInfo,
                       messageReaderSettings));
        }
        /// <summary>
        /// Detects the payload kind(s) of the payload.
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero or more payload kinds depending on what payload kinds were detected.</returns>
        /// <remarks>This method decides the payload kind based on the fully-qualified element name of the top-level Xml element 
        /// in the payload for entry, feed, entity reference link, error and service document payload kinds. It performs more checks
        /// for properties and collection payloads as follows:
        /// * If an m:type attribute is found => property
        /// * If an m:null attribute is found => property
        /// Otherwise the shape of the payload decides:
        /// * If we only find d:element child nodes => collection or property
        /// * If we find no child nodes => primitive property
        /// * If we find anything else => complex property
        /// </remarks>
        internal IEnumerable<ODataPayloadKind> DetectPayloadKind(ODataPayloadKindDetectionInfo detectionInfo)
        {
            DebugUtils.CheckNoExternalCallers();

            this.XmlReader.DisableInStreamErrorDetection = true;
            try
            {
                if (this.XmlReader.TryReadToNextElement())
                {
                    if (string.CompareOrdinal(AtomConstants.AtomNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // ATOM namespace for <entry> and <feed>
                        if (string.CompareOrdinal(AtomConstants.AtomEntryElementName, this.XmlReader.LocalName) == 0)
                        {
                            return new ODataPayloadKind[] { ODataPayloadKind.Entry };
                        }

                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.AtomFeedElementName, this.XmlReader.LocalName) == 0)
                        {
                            return new ODataPayloadKind[] { ODataPayloadKind.Feed };
                        }
                    }
                    else if (string.CompareOrdinal(AtomConstants.ODataNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // OData namespace for entity reference links, properties, collections
                        // NOTE: everything in the OData namespace is considered a property (or collection). Some of them
                        //       may have a potential other payload kind as well.
                        //
                        // Only check for property or collection if these payload kinds are even included in the possible payload kinds
                        IEnumerable<ODataPayloadKind> possiblePayloadKinds = detectionInfo.PossiblePayloadKinds;
                        IEnumerable<ODataPayloadKind> payloadKinds =
                            possiblePayloadKinds.Contains(ODataPayloadKind.Property) || possiblePayloadKinds.Contains(ODataPayloadKind.Collection)
                            ? this.DetectPropertyOrCollectionPayloadKind()
                            : Enumerable.Empty<ODataPayloadKind>();

                        if (string.CompareOrdinal(AtomConstants.ODataUriElementName, this.XmlReader.LocalName) == 0)
                        {
                            payloadKinds = payloadKinds.Concat(new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLink });
                        }

                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.ODataLinksElementName, this.XmlReader.LocalName) == 0)
                        {
                            payloadKinds = payloadKinds.Concat(new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLinks });
                        }

                        return payloadKinds;
                    }
                    else if (string.CompareOrdinal(AtomConstants.ODataMetadataNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // OData metadata namespace for errors and <m:uri> (back compat behavior instead of <d:uri>)
                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.ODataErrorElementName, this.XmlReader.LocalName) == 0)
                        {
                            return new ODataPayloadKind[] { ODataPayloadKind.Error };
                        }

                        if (string.CompareOrdinal(AtomConstants.ODataUriElementName, this.XmlReader.LocalName) == 0)
                        {
                            return new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLink };
                        }
                    }
                    else if (string.CompareOrdinal(AtomConstants.AtomPublishingNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // AtomPub namespace for service doc
                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.AtomPublishingServiceElementName, this.XmlReader.LocalName) == 0)
                        {
                            return new ODataPayloadKind[] { ODataPayloadKind.ServiceDocument };
                        }
                    }

                    //// If none of the above namespaces is found, we don't understand the payload in the ATOM format.
                }
            }
            catch (XmlException)
            {
                // If we are not able to read the payload as XML
                // return no detected payload kind below.
            }
            finally
            {
                this.XmlReader.DisableInStreamErrorDetection = false;
            }

            return Enumerable.Empty<ODataPayloadKind>();
        }
Example #20
0
 /// <summary>
 /// Detects the payload kind(s) from the message stream.
 /// </summary>
 /// <param name="messageStream">The message stream to read from for payload kind detection.</param>
 /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
 /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param>
 /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
 /// <returns>An enumerable of zero or more payload kinds depending on what payload kinds were detected.</returns>
 private IEnumerable<ODataPayloadKind> DetectPayloadKindImplementation(
     Stream messageStream,
     bool readingResponse,
     bool synchronous,
     ODataPayloadKindDetectionInfo detectionInfo)
 {
     using (ODataAtomInputContext inputContext = new ODataAtomInputContext(
         this,
         messageStream,
         detectionInfo.GetEncoding(),
         detectionInfo.MessageReaderSettings,
         readingResponse,
         synchronous,
         detectionInfo.Model,
         /*urlResolver*/ null))
     {
         return inputContext.DetectPayloadKind(detectionInfo);
     }
 }
        /// <summary>
        /// Detects the payload kind(s) of the payload.
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero or more payload kinds depending on what payload kinds were detected.</returns>
        internal IEnumerable<ODataPayloadKind> DetectPayloadKind(ODataPayloadKindDetectionInfo detectionInfo)
        {
            Debug.Assert(detectionInfo != null, "detectionInfo != null");

            ODataAtomPayloadKindDetectionDeserializer payloadKindDetectionDeserializer = new ODataAtomPayloadKindDetectionDeserializer(this);
            return payloadKindDetectionDeserializer.DetectPayloadKind(detectionInfo);
        }
Example #22
0
 internal IEnumerable <ODataPayloadKind> DetectPayloadKind(ODataPayloadKindDetectionInfo detectionInfo)
 {
     base.XmlReader.DisableInStreamErrorDetection = true;
     try
     {
         if (base.XmlReader.TryReadToNextElement())
         {
             if (string.CompareOrdinal("http://www.w3.org/2005/Atom", base.XmlReader.NamespaceURI) == 0)
             {
                 if (string.CompareOrdinal("entry", base.XmlReader.LocalName) == 0)
                 {
                     return(new ODataPayloadKind[] { ODataPayloadKind.Entry });
                 }
                 if (base.ReadingResponse && (string.CompareOrdinal("feed", base.XmlReader.LocalName) == 0))
                 {
                     return(new ODataPayloadKind[1]);
                 }
             }
             else
             {
                 if (string.CompareOrdinal("http://schemas.microsoft.com/ado/2007/08/dataservices", base.XmlReader.NamespaceURI) == 0)
                 {
                     IEnumerable <ODataPayloadKind> possiblePayloadKinds = detectionInfo.PossiblePayloadKinds;
                     IEnumerable <ODataPayloadKind> first = (possiblePayloadKinds.Contains <ODataPayloadKind>(ODataPayloadKind.Property) || possiblePayloadKinds.Contains <ODataPayloadKind>(ODataPayloadKind.Collection)) ? this.DetectPropertyOrCollectionPayloadKind() : Enumerable.Empty <ODataPayloadKind>();
                     if (string.CompareOrdinal("uri", base.XmlReader.LocalName) == 0)
                     {
                         first = first.Concat <ODataPayloadKind>(new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLink });
                     }
                     if (base.ReadingResponse && (string.CompareOrdinal("links", base.XmlReader.LocalName) == 0))
                     {
                         first = first.Concat <ODataPayloadKind>(new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLinks });
                     }
                     return(first);
                 }
                 if (string.CompareOrdinal("http://schemas.microsoft.com/ado/2007/08/dataservices/metadata", base.XmlReader.NamespaceURI) == 0)
                 {
                     if (base.ReadingResponse && (string.CompareOrdinal("error", base.XmlReader.LocalName) == 0))
                     {
                         return(new ODataPayloadKind[] { ODataPayloadKind.Error });
                     }
                     if (string.CompareOrdinal("uri", base.XmlReader.LocalName) == 0)
                     {
                         return(new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLink });
                     }
                 }
                 else if (((string.CompareOrdinal("http://www.w3.org/2007/app", base.XmlReader.NamespaceURI) == 0) && base.ReadingResponse) && (string.CompareOrdinal("service", base.XmlReader.LocalName) == 0))
                 {
                     return(new ODataPayloadKind[] { ODataPayloadKind.ServiceDocument });
                 }
             }
         }
     }
     catch (XmlException)
     {
     }
     finally
     {
         base.XmlReader.DisableInStreamErrorDetection = false;
     }
     return(Enumerable.Empty <ODataPayloadKind>());
 }
Example #23
0
        internal override IEnumerable <ODataPayloadKind> DetectPayloadKind(IODataResponseMessage responseMessage, ODataPayloadKindDetectionInfo detectionInfo)
        {
            ExceptionUtils.CheckArgumentNotNull <IODataResponseMessage>(responseMessage, "responseMessage");
            ExceptionUtils.CheckArgumentNotNull <ODataPayloadKindDetectionInfo>(detectionInfo, "detectionInfo");
            Stream messageStream = ((ODataMessage)responseMessage).GetStream();

            return(this.DetectPayloadKindImplementation(messageStream, true, true, detectionInfo));
        }
        /// <summary>
        /// Detects the payload kind(s).
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        private IEnumerable<ODataPayloadKind> DetectPayloadKindImplementation(ODataPayloadKindDetectionInfo detectionInfo)
        {
            Debug.Assert(detectionInfo != null, "detectionInfo != null");
            Debug.Assert(this.JsonReader.DisableInStreamErrorDetection, "The in-stream error detection should be disabled for payload kind detection.");

            this.AssertJsonCondition(JsonNodeType.Property, JsonNodeType.EndObject);

            // If we found a context URI and parsed it, look at the detected payload kind and return it.
            if (this.ContextUriParseResult != null)
            {
                return this.ContextUriParseResult.DetectedPayloadKinds;
            }

            // Otherwise this is a payload without context URI and we have to start sniffing; only error payloads
            // don't have a context URI so check for a single 'error' property (ignoring custom annotations).
            ODataError error = null;
            while (this.JsonReader.NodeType == JsonNodeType.Property)
            {
                string propertyName = this.JsonReader.ReadPropertyName();
                string annotatedPropertyName, annotationName;
                if (!ODataJsonLightDeserializer.TryParsePropertyAnnotation(propertyName, out annotatedPropertyName, out annotationName))
                {
                    if (ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName))
                    {
                        if (propertyName != null && propertyName.StartsWith(JsonLightConstants.ODataPropertyAnnotationSeparatorChar + JsonLightConstants.ODataAnnotationNamespacePrefix, System.StringComparison.Ordinal))
                        {
                            // Any @odata.* instance annotations are not allowed for errors.
                            return Enumerable.Empty<ODataPayloadKind>();
                        }
                        else
                        {
                            // Skip custom instance annotations
                            this.JsonReader.SkipValue();
                        }
                    }
                    else
                    {
                        if (string.CompareOrdinal(JsonLightConstants.ODataErrorPropertyName, propertyName) == 0)
                        {
                            // If we find multiple errors or an invalid error value, this is not an error payload.
                            if (error != null || !this.JsonReader.StartBufferingAndTryToReadInStreamErrorPropertyValue(out error))
                            {
                                return Enumerable.Empty<ODataPayloadKind>();
                            }

                            // At this point we successfully read the first error property. 
                            // Skip the error value and check whether there are more properties.
                            this.JsonReader.SkipValue();
                        }
                        else
                        {
                            // if it contains non-annotation property, it is not an error payload.
                            return Enumerable.Empty<ODataPayloadKind>();
                        }
                    }
                }
                else
                {
                    // Property annotation
                    return Enumerable.Empty<ODataPayloadKind>();
                }
            }

            // If we got here without finding a context URI or an error payload, we don't know what this is.
            if (error == null)
            {
                return Enumerable.Empty<ODataPayloadKind>();
            }

            return new ODataPayloadKind[] { ODataPayloadKind.Error };
        }
        /// <summary>
        /// Detects the payload kind(s).
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        private IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(ODataPayloadKindDetectionInfo detectionInfo)
        {
            Debug.Assert(detectionInfo != null, "detectionInfo != null");
            Debug.Assert(this.JsonReader.DisableInStreamErrorDetection, "The in-stream error detection should be disabled for payload kind detection.");

            this.AssertJsonCondition(JsonNodeType.Property, JsonNodeType.EndObject);

            // If we found a context URI and parsed it, look at the detected payload kind and return it.
            if (this.ContextUriParseResult != null)
            {
                return(this.ContextUriParseResult.DetectedPayloadKinds);
            }

            // Otherwise this is a payload without context URI and we have to start sniffing; only error payloads
            // don't have a context URI so check for a single 'error' property (ignoring custom annotations).
            ODataError error = null;

            while (this.JsonReader.NodeType == JsonNodeType.Property)
            {
                string propertyName = this.JsonReader.ReadPropertyName();
                string annotatedPropertyName, annotationName;
                if (!ODataJsonLightDeserializer.TryParsePropertyAnnotation(propertyName, out annotatedPropertyName, out annotationName))
                {
                    if (ODataJsonLightReaderUtils.IsAnnotationProperty(propertyName))
                    {
                        if (propertyName != null && propertyName.StartsWith(JsonLightConstants.ODataPropertyAnnotationSeparatorChar + JsonLightConstants.ODataAnnotationNamespacePrefix, System.StringComparison.Ordinal))
                        {
                            // Any @odata.* instance annotations are not allowed for errors.
                            return(Enumerable.Empty <ODataPayloadKind>());
                        }
                        else
                        {
                            // Skip custom instance annotations
                            this.JsonReader.SkipValue();
                        }
                    }
                    else
                    {
                        if (string.CompareOrdinal(JsonLightConstants.ODataErrorPropertyName, propertyName) == 0)
                        {
                            // If we find multiple errors or an invalid error value, this is not an error payload.
                            if (error != null || !this.JsonReader.StartBufferingAndTryToReadInStreamErrorPropertyValue(out error))
                            {
                                return(Enumerable.Empty <ODataPayloadKind>());
                            }

                            // At this point we successfully read the first error property.
                            // Skip the error value and check whether there are more properties.
                            this.JsonReader.SkipValue();
                        }
                        else
                        {
                            // if it contains non-annotation property, it is not an error payload.
                            return(Enumerable.Empty <ODataPayloadKind>());
                        }
                    }
                }
                else
                {
                    // Property annotation
                    return(Enumerable.Empty <ODataPayloadKind>());
                }
            }

            // If we got here without finding a context URI or an error payload, we don't know what this is.
            if (error == null)
            {
                return(Enumerable.Empty <ODataPayloadKind>());
            }

            return(new ODataPayloadKind[] { ODataPayloadKind.Error });
        }
Example #26
0
        internal IEnumerable <ODataPayloadKind> DetectPayloadKind(ODataPayloadKindDetectionInfo detectionInfo)
        {
            ODataAtomPayloadKindDetectionDeserializer deserializer = new ODataAtomPayloadKindDetectionDeserializer(this);

            return(deserializer.DetectPayloadKind(detectionInfo));
        }
        /// <summary>
        /// Detects the payload kind(s) of the payload.
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero or more payload kinds depending on what payload kinds were detected.</returns>
        /// <remarks>This method decides the payload kind based on the fully-qualified element name of the top-level Xml element 
        /// in the payload for entry, feed, entity reference link, error and service document payload kinds. It performs more checks
        /// for properties and collection payloads as follows:
        /// * If an m:type attribute is found => property
        /// * If an m:null attribute is found => property
        /// Otherwise the shape of the payload decides:
        /// * If we only find m:element child nodes => collection or property
        /// * If we find no child nodes => primitive property
        /// * If we find anything else => complex property
        /// </remarks>
        internal IEnumerable<ODataPayloadKind> DetectPayloadKind(ODataPayloadKindDetectionInfo detectionInfo)
        {
            this.XmlReader.DisableInStreamErrorDetection = true;
            try
            {
                if (this.XmlReader.TryReadToNextElement())
                {
                    if (string.CompareOrdinal(AtomConstants.AtomNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // ATOM namespace for <entry> and <feed>
                        if (string.CompareOrdinal(AtomConstants.AtomEntryElementName, this.XmlReader.LocalName) == 0)
                        {
                            return new ODataPayloadKind[] { ODataPayloadKind.Entry };
                        }

                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.AtomFeedElementName, this.XmlReader.LocalName) == 0)
                        {
                            if (this.XmlReader.XmlBaseUri != null
                                && this.XmlReader.XmlBaseUri.AbsoluteUri.Contains(ODataConstants.EntityReferenceSegmentName))
                            {
                                return new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLinks };
                            }
                            else
                            {
                                return new ODataPayloadKind[] { ODataPayloadKind.Feed };
                            }
                        }
                    }
                    else if (string.CompareOrdinal(AtomConstants.ODataNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // Will figure out whether we need to remove this part of logic, since in the top level, the format has been changed to <m:value
                        // OData namespace for entity reference links, properties, collections
                        // NOTE: everything in the OData namespace is considered a property (or collection). Some of them
                        //       may have a potential other payload kind as well.
                        return this.DetectPropertyOrCollectionPayloadKind();
                    }
                    else if (string.CompareOrdinal(AtomConstants.ODataMetadataNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // OData metadata namespace for collections
                        // Only check for property or collection if these payload kinds are even included in the possible payload kinds
                        if (string.CompareOrdinal(AtomConstants.ODataValueElementName, this.XmlReader.LocalName) == 0)
                        {
                            return this.DetectPropertyOrCollectionPayloadKind();
                        }

                        // OData metadata namespace for errors and <m:ref>
                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.ODataErrorElementName, this.XmlReader.LocalName) == 0)
                        {
                            return new ODataPayloadKind[] { ODataPayloadKind.Error };
                        }

                        if (string.CompareOrdinal(AtomConstants.ODataRefElementName, this.XmlReader.LocalName) == 0)
                        {
                            return new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLink };
                        }
                    }
                    else if (string.CompareOrdinal(AtomConstants.AtomPublishingNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // AtomPub namespace for service doc
                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.AtomPublishingServiceElementName, this.XmlReader.LocalName) == 0)
                        {
                            return new ODataPayloadKind[] { ODataPayloadKind.ServiceDocument };
                        }
                    }

                    //// If none of the above namespaces is found, we don't understand the payload in the ATOM format.
                }
            }
            catch (XmlException)
            {
                // If we are not able to read the payload as XML
                // return no detected payload kind below.
            }
            finally
            {
                this.XmlReader.DisableInStreamErrorDetection = false;
            }

            return Enumerable.Empty<ODataPayloadKind>();
        }
Example #28
0
 internal override Task <IEnumerable <ODataPayloadKind> > DetectPayloadKindAsync(IODataResponseMessageAsync responseMessage, ODataPayloadKindDetectionInfo detectionInfo)
 {
     ExceptionUtils.CheckArgumentNotNull <IODataResponseMessageAsync>(responseMessage, "responseMessage");
     ExceptionUtils.CheckArgumentNotNull <ODataPayloadKindDetectionInfo>(detectionInfo, "detectionInfo");
     return(((ODataMessage)responseMessage).GetStreamAsync().FollowOnSuccessWith <Stream, IEnumerable <ODataPayloadKind> >(streamTask => this.DetectPayloadKindImplementation(streamTask.Result, true, false, detectionInfo)));
 }
        /// <summary>
        /// Detects the payload kind(s) from the message stream.
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>A task which returns an enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        internal Task<IEnumerable<ODataPayloadKind>> DetectPayloadKindAsync(ODataPayloadKindDetectionInfo detectionInfo)
        {
            Debug.Assert(detectionInfo != null, "detectionInfo != null");
            this.VerifyCanDetectPayloadKind();

            ODataJsonLightPayloadKindDetectionDeserializer payloadKindDetectionDeserializer = new ODataJsonLightPayloadKindDetectionDeserializer(this);
            return payloadKindDetectionDeserializer.DetectPayloadKindAsync(detectionInfo);
        }
Example #30
0
        /// <summary>
        /// Detects the payload kind(s) of the payload.
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero or more payload kinds depending on what payload kinds were detected.</returns>
        /// <remarks>This method decides the payload kind based on the fully-qualified element name of the top-level Xml element
        /// in the payload for entry, feed, entity reference link, error and service document payload kinds. It performs more checks
        /// for properties and collection payloads as follows:
        /// * If an m:type attribute is found => property
        /// * If an m:null attribute is found => property
        /// Otherwise the shape of the payload decides:
        /// * If we only find d:element child nodes => collection or property
        /// * If we find no child nodes => primitive property
        /// * If we find anything else => complex property
        /// </remarks>
        internal IEnumerable <ODataPayloadKind> DetectPayloadKind(ODataPayloadKindDetectionInfo detectionInfo)
        {
            DebugUtils.CheckNoExternalCallers();

            this.XmlReader.DisableInStreamErrorDetection = true;
            try
            {
                if (this.XmlReader.TryReadToNextElement())
                {
                    if (string.CompareOrdinal(AtomConstants.AtomNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // ATOM namespace for <entry> and <feed>
                        if (string.CompareOrdinal(AtomConstants.AtomEntryElementName, this.XmlReader.LocalName) == 0)
                        {
                            return(new ODataPayloadKind[] { ODataPayloadKind.Entry });
                        }

                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.AtomFeedElementName, this.XmlReader.LocalName) == 0)
                        {
                            return(new ODataPayloadKind[] { ODataPayloadKind.Feed });
                        }
                    }
                    else if (string.CompareOrdinal(AtomConstants.ODataNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // OData namespace for entity reference links, properties, collections
                        // NOTE: everything in the OData namespace is considered a property (or collection). Some of them
                        //       may have a potential other payload kind as well.
                        //
                        // Only check for property or collection if these payload kinds are even included in the possible payload kinds
                        IEnumerable <ODataPayloadKind> possiblePayloadKinds = detectionInfo.PossiblePayloadKinds;
                        IEnumerable <ODataPayloadKind> payloadKinds         =
                            possiblePayloadKinds.Any(k => k == ODataPayloadKind.Property || k == ODataPayloadKind.Collection)
                            ? this.DetectPropertyOrCollectionPayloadKind()
                            : Enumerable.Empty <ODataPayloadKind>();

                        if (string.CompareOrdinal(AtomConstants.ODataUriElementName, this.XmlReader.LocalName) == 0)
                        {
                            payloadKinds = payloadKinds.Concat(new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLink });
                        }

                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.ODataLinksElementName, this.XmlReader.LocalName) == 0)
                        {
                            payloadKinds = payloadKinds.Concat(new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLinks });
                        }

                        return(payloadKinds);
                    }
                    else if (string.CompareOrdinal(AtomConstants.ODataMetadataNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // OData metadata namespace for errors and <m:uri> (back compat behavior instead of <d:uri>)
                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.ODataErrorElementName, this.XmlReader.LocalName) == 0)
                        {
                            return(new ODataPayloadKind[] { ODataPayloadKind.Error });
                        }

                        if (string.CompareOrdinal(AtomConstants.ODataUriElementName, this.XmlReader.LocalName) == 0)
                        {
                            return(new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLink });
                        }
                    }
                    else if (string.CompareOrdinal(AtomConstants.AtomPublishingNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // AtomPub namespace for service doc
                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.AtomPublishingServiceElementName, this.XmlReader.LocalName) == 0)
                        {
                            return(new ODataPayloadKind[] { ODataPayloadKind.ServiceDocument });
                        }
                    }

                    //// If none of the above namespaces is found, we don't understand the payload in the ATOM format.
                }
            }
            catch (XmlException)
            {
                // If we are not able to read the payload as XML
                // return no detected payload kind below.
            }
            finally
            {
                this.XmlReader.DisableInStreamErrorDetection = false;
            }

            return(Enumerable.Empty <ODataPayloadKind>());
        }
Example #31
0
 private IEnumerable <ODataPayloadKind> DetectPayloadKindImplementation(Stream messageStream, bool readingResponse, bool synchronous, ODataPayloadKindDetectionInfo detectionInfo)
 {
     using (ODataAtomInputContext context = new ODataAtomInputContext(this, messageStream, detectionInfo.GetEncoding(), detectionInfo.MessageReaderSettings, ODataVersion.V3, readingResponse, synchronous, detectionInfo.Model, null))
     {
         return(context.DetectPayloadKind(detectionInfo));
     }
 }
Example #32
0
 /// <summary>
 /// Detects the payload kind(s) from the message stream.
 /// </summary>
 /// <param name="messageStream">The message stream to read from for payload kind detection.</param>
 /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
 /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param>
 /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
 /// <returns>An enumerable of zero or more payload kinds depending on what payload kinds were detected.</returns>
 private IEnumerable<ODataPayloadKind> DetectPayloadKindImplementation(
     Stream messageStream,
     bool readingResponse,
     bool synchronous,
     ODataPayloadKindDetectionInfo detectionInfo)
 {
     using (ODataAtomInputContext inputContext = new ODataAtomInputContext(
         this,
         messageStream,
         detectionInfo.GetEncoding(),
         detectionInfo.MessageReaderSettings,
         ODataVersion.V3,    // NOTE: we don't rely on the version for payload kind detection; taking the latest.
         readingResponse,
         synchronous,
         detectionInfo.Model,
         /*urlResolver*/ null))
     {
         return inputContext.DetectPayloadKind(detectionInfo);
     }
 }
        /// <summary>
        /// Detects the payload kind(s) of the payload.
        /// </summary>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero or more payload kinds depending on what payload kinds were detected.</returns>
        /// <remarks>This method decides the payload kind based on the fully-qualified element name of the top-level Xml element
        /// in the payload for entry, feed, entity reference link, error and service document payload kinds. It performs more checks
        /// for properties and collection payloads as follows:
        /// * If an m:type attribute is found => property
        /// * If an m:null attribute is found => property
        /// Otherwise the shape of the payload decides:
        /// * If we only find m:element child nodes => collection or property
        /// * If we find no child nodes => primitive property
        /// * If we find anything else => complex property
        /// </remarks>
        internal IEnumerable <ODataPayloadKind> DetectPayloadKind(ODataPayloadKindDetectionInfo detectionInfo)
        {
            this.XmlReader.DisableInStreamErrorDetection = true;
            try
            {
                if (this.XmlReader.TryReadToNextElement())
                {
                    if (string.CompareOrdinal(AtomConstants.AtomNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // ATOM namespace for <entry> and <feed>
                        if (string.CompareOrdinal(AtomConstants.AtomEntryElementName, this.XmlReader.LocalName) == 0)
                        {
                            return(new ODataPayloadKind[] { ODataPayloadKind.Entry });
                        }

                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.AtomFeedElementName, this.XmlReader.LocalName) == 0)
                        {
                            if (this.XmlReader.XmlBaseUri != null &&
                                this.XmlReader.XmlBaseUri.AbsoluteUri.Contains(ODataConstants.EntityReferenceSegmentName))
                            {
                                return(new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLinks });
                            }
                            else
                            {
                                return(new ODataPayloadKind[] { ODataPayloadKind.Feed });
                            }
                        }
                    }
                    else if (string.CompareOrdinal(AtomConstants.ODataNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // Will figure out whether we need to remove this part of logic, since in the top level, the format has been changed to <m:value
                        // OData namespace for entity reference links, properties, collections
                        // NOTE: everything in the OData namespace is considered a property (or collection). Some of them
                        //       may have a potential other payload kind as well.
                        //
                        // Only check for property or collection if these payload kinds are even included in the possible payload kinds
                        IEnumerable <ODataPayloadKind> possiblePayloadKinds = detectionInfo.PossiblePayloadKinds;
                        IEnumerable <ODataPayloadKind> payloadKinds         =
                            possiblePayloadKinds.Any(k => k == ODataPayloadKind.Property || k == ODataPayloadKind.Collection)
                            ? this.DetectPropertyOrCollectionPayloadKind()
                            : Enumerable.Empty <ODataPayloadKind>();

                        return(payloadKinds);
                    }
                    else if (string.CompareOrdinal(AtomConstants.ODataMetadataNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // OData metadata namespace for collections
                        // Only check for property or collection if these payload kinds are even included in the possible payload kinds
                        if (string.CompareOrdinal(AtomConstants.ODataValueElementName, this.XmlReader.LocalName) == 0)
                        {
                            IEnumerable <ODataPayloadKind> possiblePayloadKinds = detectionInfo.PossiblePayloadKinds;
                            IEnumerable <ODataPayloadKind> payloadKinds         =
                                possiblePayloadKinds.Any(k => k == ODataPayloadKind.Property || k == ODataPayloadKind.Collection)
                                ? this.DetectPropertyOrCollectionPayloadKind()
                                : Enumerable.Empty <ODataPayloadKind>();
                            return(payloadKinds);
                        }

                        // OData metadata namespace for errors and <m:ref>
                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.ODataErrorElementName, this.XmlReader.LocalName) == 0)
                        {
                            return(new ODataPayloadKind[] { ODataPayloadKind.Error });
                        }

                        if (string.CompareOrdinal(AtomConstants.ODataRefElementName, this.XmlReader.LocalName) == 0)
                        {
                            return(new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLink });
                        }
                    }
                    else if (string.CompareOrdinal(AtomConstants.AtomPublishingNamespace, this.XmlReader.NamespaceURI) == 0)
                    {
                        // AtomPub namespace for service doc
                        if (this.ReadingResponse && string.CompareOrdinal(AtomConstants.AtomPublishingServiceElementName, this.XmlReader.LocalName) == 0)
                        {
                            return(new ODataPayloadKind[] { ODataPayloadKind.ServiceDocument });
                        }
                    }

                    //// If none of the above namespaces is found, we don't understand the payload in the ATOM format.
                }
            }
            catch (XmlException)
            {
                // If we are not able to read the payload as XML
                // return no detected payload kind below.
            }
            finally
            {
                this.XmlReader.DisableInStreamErrorDetection = false;
            }

            return(Enumerable.Empty <ODataPayloadKind>());
        }
Example #34
0
        /// <summary>
        /// Asynchronously detects the payload kinds supported by this format for the specified message payload.
        /// </summary>
        /// <param name="responseMessage">The response message with the payload stream.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>A task that when completed returns the set of <see cref="ODataPayloadKind"/>s 
        /// that are supported with the specified payload.</returns>
        internal override Task<IEnumerable<ODataPayloadKind>> DetectPayloadKindAsync(
            IODataResponseMessageAsync responseMessage,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            DebugUtils.CheckNoExternalCallers();
            ExceptionUtils.CheckArgumentNotNull(responseMessage, "responseMessage");
            ExceptionUtils.CheckArgumentNotNull(detectionInfo, "detectionInfo");

            // NOTE: After getting the message stream we already (asynchronously) buffered the whole stream in memory (in the AsyncBufferedStream).
            //       Until we get Task-based async stream APIs and retire the AsyncBufferedStream, we call the synchronous method on the buffered stream.
            return ((ODataMessage)responseMessage).GetStreamAsync()
                .FollowOnSuccessWith(streamTask => this.DetectPayloadKindImplementation(streamTask.Result, /*readingResponse*/ true, /*synchronous*/ false, detectionInfo));
        }
Example #35
0
        /// <summary>
        /// Detects the payload kind(s) from the message stream.
        /// </summary>
        /// <param name="messageStream">The message stream to read from for payload kind detection.</param>
        /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
        /// <param name="detectionInfo">Additional information available for the payload kind detection.</param>
        /// <returns>An enumerable of zero, one or more payload kinds that were detected from looking at the payload in the message stream.</returns>
        private Task<IEnumerable<ODataPayloadKind>> DetectPayloadKindImplementationAsync(
            Stream messageStream,
            bool readingResponse,
            ODataPayloadKindDetectionInfo detectionInfo)
        {
            ODataJsonLightInputContext jsonLightInputContext = new ODataJsonLightInputContext(
                this,
                messageStream,
                detectionInfo.ContentType,
                detectionInfo.GetEncoding(),
                detectionInfo.MessageReaderSettings,
                readingResponse,
                /*synchronous*/ false,
                detectionInfo.Model,
                /*urlResolver*/ null);

            return jsonLightInputContext.DetectPayloadKindAsync(detectionInfo)
                .FollowAlwaysWith(t =>
                    {
                        jsonLightInputContext.Dispose();
                    });
        }