Пример #1
0
        /// <summary>
        /// Create context URL from ODataPayloadKind and ODataContextUrlInfo.
        /// should make the context uri correct for null primitive / null enum value / normal enum value
        /// ODataEnumValue is allowed to have null or arbitrary TypeName, but the output ContextUri must have correct type name.
        /// </summary>
        /// <param name="payloadKind">The ODataPayloadKind for the context URI.</param>
        /// <param name="contextInfo">The ODataContextUrlInfo to be used.</param>
        /// <returns>The generated context url.</returns>
        internal Uri BuildContextUri(ODataPayloadKind payloadKind, ODataContextUrlInfo contextInfo = null)
        {
            if (this.baseContextUrl == null)
            {
                return null;
            }

            Action<ODataContextUrlInfo> verifyAction;
            if (ValidationDictionary.TryGetValue(payloadKind, out verifyAction))
            {
                if (verifyAction != null && throwIfMissingInfo)
                {
                    Debug.Assert(contextInfo != null, "contextInfo != null");
                    verifyAction(contextInfo);
                }
            }
            else
            {
                throw new ODataException(Strings.ODataContextUriBuilder_UnsupportedPayloadKind(payloadKind.ToString()));
            }

            switch (payloadKind)
            {
                case ODataPayloadKind.ServiceDocument:
                    return this.baseContextUrl;
                case ODataPayloadKind.EntityReferenceLink:
                    return new Uri(this.baseContextUrl, ODataConstants.SingleEntityReferencesContextUrlSegment);
                case ODataPayloadKind.EntityReferenceLinks:
                    return new Uri(this.baseContextUrl, ODataConstants.CollectionOfEntityReferencesContextUrlSegment);
            }

            return CreateFromContextUrlInfo(contextInfo);
        }
        /// <summary>
        /// Determines the response format based on the results of content negotiation.
        /// </summary>
        /// <param name="payloadKind">The payload kind of the response.</param>
        /// <param name="acceptableMediaTypes">
        /// The acceptable media types used to determine the content type of the message.
        /// This is a comma separated list of content types as specified in RFC 2616, Section 14.1
        /// </param>
        /// <param name="acceptableCharSets">
        /// The acceptable charsets to use to the determine the encoding of the message.
        /// This is a comma separated list of charsets as specified in RFC 2616, Section 14.2
        /// </param>
        /// <returns>The format the response should use. </returns>
        internal ODataFormatWithParameters DetermineResponseFormat(ODataPayloadKind payloadKind, string acceptableMediaTypes, string acceptableCharSets)
        {
            Debug.Assert(payloadKind != ODataPayloadKind.Unsupported, "kind != ODataPayloadKind.Unsupported");

            ContentNegotiationResponseMessage responseMessage = new ContentNegotiationResponseMessage();

            ODataMessageWriterSettings settings = new ODataMessageWriterSettings { Version = this.responseVersion };
            settings.EnableAtomSupport();
            settings.SetContentType(acceptableMediaTypes, acceptableCharSets);

            try
            {
                using (ODataMessageWriter writer = new ODataMessageWriter(responseMessage, settings))
                {
                    ODataFormat format = ODataUtils.SetHeadersForPayload(writer, payloadKind);
                    return new ODataFormatWithParameters(format, responseMessage.ContentType);
                }
            }
            catch (ODataContentTypeException exception)
            {
                if (this.throwIfNoMatch)
                {
                    throw new DataServiceException(415, null, Microsoft.OData.Service.Strings.DataServiceException_UnsupportedMediaType, null, exception);
                }

                return null;
            }
        }
Пример #3
0
        internal static bool IsPayloadKindSupported(ODataPayloadKind payloadKind, bool inRequest)
        {
            switch (payloadKind)
            {
                case ODataPayloadKind.Feed:
                case ODataPayloadKind.EntityReferenceLinks:
                case ODataPayloadKind.Collection:
                case ODataPayloadKind.ServiceDocument:
                case ODataPayloadKind.MetadataDocument:
                case ODataPayloadKind.Error:
                    return !inRequest;

                case ODataPayloadKind.Entry:
                case ODataPayloadKind.Property:
                case ODataPayloadKind.EntityReferenceLink:
                case ODataPayloadKind.Value:
                case ODataPayloadKind.BinaryValue:
                case ODataPayloadKind.Batch:
                    return true;

                case ODataPayloadKind.Parameter:
                    return inRequest;
            }
            throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataUtilsInternal_IsPayloadKindSupported_UnreachableCodePath));
        }
        /// <summary>
        /// Creates a context URI parser and parses the context URI read from the payload.
        /// </summary>
        /// <param name="model">The model to use when resolving the target of the URI.</param>
        /// <param name="contextUriFromPayload">The string value of the odata.metadata annotation read from the payload.</param>
        /// <param name="payloadKind">The payload kind we expect the context URI to conform to.</param>
        /// <param name="readerBehavior">Reader behavior if the caller is a reader, null if no reader behavior is available.</param>
        /// <param name="needParseFragment">Whether the fragment after $metadata should be parsed, if set to false, only MetadataDocumentUri is parsed.</param>
        /// <returns>The result from parsing the context URI.</returns>
        internal static ODataJsonLightContextUriParseResult Parse(
            IEdmModel model,
            string contextUriFromPayload,
            ODataPayloadKind payloadKind,
            ODataReaderBehavior readerBehavior,
            bool needParseFragment)
        {
            if (contextUriFromPayload == null)
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_NullMetadataDocumentUri);
            }

            // Create an absolute URI from the payload string
            // TODO: Support relative context uri and resolving other relative uris
            Uri contextUri;
            if (!Uri.TryCreate(contextUriFromPayload, UriKind.Absolute, out contextUri))
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_TopLevelContextUrlShouldBeAbsolute(contextUriFromPayload));
            }

            ODataJsonLightContextUriParser parser = new ODataJsonLightContextUriParser(model, contextUri);

            parser.TokenizeContextUri();
            if (needParseFragment)
            {
                parser.ParseContextUri(payloadKind, readerBehavior);
            }

            return parser.parseResult;
        }
Пример #5
0
        internal ODataRawInputContext(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageReaderSettings messageReaderSettings,
            bool readingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver,
            ODataPayloadKind readerPayloadKind)
            : base(format, messageReaderSettings, readingResponse, synchronous, model, urlResolver)
        {
            Debug.Assert(messageStream != null, "stream != null");
            Debug.Assert(readerPayloadKind != ODataPayloadKind.Unsupported, "readerPayloadKind != ODataPayloadKind.Unsupported");

            ExceptionUtils.CheckArgumentNotNull(format, "format");
            ExceptionUtils.CheckArgumentNotNull(messageReaderSettings, "messageReaderSettings");

            try
            {
                this.stream = messageStream;
                this.encoding = encoding;
                this.readerPayloadKind = readerPayloadKind;
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
 public static void Validate(ODataPayloadKind payloadKind, string parameterName)
 {
     if (!IsDefined(payloadKind))
     {
         throw Error.InvalidEnumArgument(parameterName, (int)payloadKind, typeof(ODataPayloadKind));
     }
 }
Пример #7
0
        public override IEnumerable<ODataMediaTypeFormat> GetMediaTypeFormats(ODataPayloadKind payloadKind)
        {
            if (payloadKind == ODataPayloadKind.Property)
            {
                return mediaTypeFormats.Concat(base.GetMediaTypeFormats(payloadKind));
            }

            return base.GetMediaTypeFormats(payloadKind);
        }
Пример #8
0
 internal ResponseBodyWriter(bool hasMoved, IDataService service, IEnumerator queryResults, RequestDescription requestDescription, IODataResponseMessage responseMessage, ODataPayloadKind payloadKind)
 {
     this.hasMoved = hasMoved;
     this.service = service;
     this.queryResults = queryResults;
     this.requestDescription = requestDescription;
     this.responseMessage = responseMessage;
     this.payloadKind = payloadKind;
     this.encoding = HttpProcessUtility.EncodingFromAcceptCharset(this.service.OperationContext.Host.RequestAcceptCharSet);
     if ((((payloadKind == ODataPayloadKind.Entry) || (payloadKind == ODataPayloadKind.Feed)) || ((payloadKind == ODataPayloadKind.Property) || (payloadKind == ODataPayloadKind.Collection))) || (((payloadKind == ODataPayloadKind.EntityReferenceLink) || (payloadKind == ODataPayloadKind.EntityReferenceLinks)) || (((payloadKind == ODataPayloadKind.Error) || (payloadKind == ODataPayloadKind.ServiceDocument)) || (payloadKind == ODataPayloadKind.Parameter))))
     {
         DataServiceHostWrapper host = service.OperationContext.Host;
         if (WebUtil.GetEffectiveMaxResponseVersion(service.Configuration.DataServiceBehavior.MaxProtocolVersion, host.RequestMaxVersion) > RequestDescription.Version2Dot0)
         {
             bool isEntityOrFeed = (payloadKind == ODataPayloadKind.Entry) || (payloadKind == ODataPayloadKind.Feed);
             if (WebUtil.ResponseMediaTypeWouldBeJsonLight(host.RequestAccept, isEntityOrFeed))
             {
                 requestDescription.VerifyAndRaiseResponseVersion(RequestDescription.Version3Dot0, service);
                 host.ResponseVersion = RequestDescription.Version3Dot0.ToString() + ";";
             }
         }
     }
     if (this.requestDescription.TargetKind == RequestTargetKind.MediaResource)
     {
         this.mediaResourceStream = service.StreamProvider.GetReadStream(this.queryResults.Current, RequestDescription.GetStreamProperty(this.requestDescription), this.service.OperationContext);
     }
     else if (payloadKind != ODataPayloadKind.BinaryValue)
     {
         string requestAcceptCharSet = this.service.OperationContext.Host.RequestAcceptCharSet;
         if (string.IsNullOrEmpty(requestAcceptCharSet) || (requestAcceptCharSet == "*"))
         {
             requestAcceptCharSet = "UTF-8";
         }
         if ((payloadKind == ODataPayloadKind.Value) && !string.IsNullOrEmpty(this.requestDescription.MimeType))
         {
             this.messageWriter = CreateMessageWriter(this.AbsoluteServiceUri, this.service, this.requestDescription.ActualResponseVersion, responseMessage, ODataFormat.RawValue);
         }
         else
         {
             this.messageWriter = CreateMessageWriter(this.AbsoluteServiceUri, this.service, this.requestDescription.ActualResponseVersion, responseMessage, this.service.OperationContext.Host.RequestAccept, requestAcceptCharSet);
         }
         try
         {
             this.contentFormat = ODataUtils.SetHeadersForPayload(this.messageWriter, payloadKind);
             if ((payloadKind == ODataPayloadKind.Value) && !string.IsNullOrEmpty(this.requestDescription.MimeType))
             {
                 responseMessage.SetHeader("Content-Type", this.requestDescription.MimeType);
             }
         }
         catch (ODataContentTypeException exception)
         {
             throw new DataServiceException(0x19f, null, System.Data.Services.Strings.DataServiceException_UnsupportedMediaType, null, exception);
         }
         string headerValue = this.requestDescription.ResponseVersion.ToString() + ";";
         responseMessage.SetHeader("DataServiceVersion", headerValue);
     }
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataEntryDeserializer"/> class.
        /// </summary>
        /// <param name="edmType">The EDM type.</param>
        /// <param name="payloadKind">The kind of OData payload that this deserializer reads.</param>
        protected ODataEntryDeserializer(IEdmTypeReference edmType, ODataPayloadKind payloadKind)
            : base(payloadKind)
        {
            if (edmType == null)
            {
                throw Error.ArgumentNull("edmType");
            }

            EdmType = edmType;
        }
Пример #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataEdmTypeSerializer"/> class.
        /// </summary>
        /// <param name="payloadKind">The kind of OData payload that this serializer generates.</param>
        /// <param name="serializerProvider">The <see cref="ODataSerializerProvider"/> to use to write inner objects.</param>
        protected ODataEdmTypeSerializer(ODataPayloadKind payloadKind, ODataSerializerProvider serializerProvider)
            : this(payloadKind)
        {
            if (serializerProvider == null)
            {
                throw Error.ArgumentNull("serializerProvider");
            }

            SerializerProvider = serializerProvider;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ODataEdmTypeDeserializer"/> class.
        /// </summary>
        /// <param name="payloadKind">The kind of OData payload this deserializer handles.</param>
        /// <param name="deserializerProvider">The <see cref="ODataDeserializerProvider"/>.</param>
        protected ODataEdmTypeDeserializer(ODataPayloadKind payloadKind, ODataDeserializerProvider deserializerProvider)
            : this(payloadKind)
        {
            if (deserializerProvider == null)
            {
                throw Error.ArgumentNull("deserializerProvider");
            }

            DeserializerProvider = deserializerProvider;
        }
        protected ODataEntrySerializer(IEdmTypeReference edmType, ODataPayloadKind odataPayloadKind, ODataSerializerProvider serializerProvider)
            : this(edmType, odataPayloadKind)
        {
            if (serializerProvider == null)
            {
                throw Error.ArgumentNull("serializerProvider");
            }

            SerializerProvider = serializerProvider;
        }
Пример #13
0
 internal MaterializeAtom(ResponseInfo responseInfo, QueryComponents queryComponents, ProjectionPlan plan, IODataResponseMessage responseMessage, ODataPayloadKind payloadKind)
 {
     Type type;
     this.responseInfo = responseInfo;
     this.elementType = queryComponents.LastSegmentType;
     this.MergeOptionValue = responseInfo.MergeOption;
     this.expectingPrimitiveValue = PrimitiveType.IsKnownNullableType(this.elementType);
     Type materializerType = GetTypeForMaterializer(this.expectingPrimitiveValue, this.elementType, responseInfo.MaxProtocolVersion, out type);
     this.materializer = ODataMaterializer.CreateMaterializerForMessage(responseMessage, responseInfo, materializerType, queryComponents, plan, payloadKind);
 }
Пример #14
0
        /// <summary>Sets the content-type and OData-Version headers on the message used by the message writer.</summary>
        /// <returns>The content-type and OData-Version headers on the message used by the message writer.</returns>
        /// <param name="messageWriter">The message writer to set the headers for.</param>
        /// <param name="payloadKind">The kind of payload to be written with the message writer.</param>
        /// <remarks>
        /// This method can be called if it is important to set all the message headers before calling any of the
        /// write methods on the <paramref name="messageWriter"/>.
        /// If it is sufficient to set the headers when the write methods on the <paramref name="messageWriter"/> 
        /// are called, you don't have to call this method and setting the headers will happen automatically.
        /// </remarks>
        public static ODataFormat SetHeadersForPayload(ODataMessageWriter messageWriter, ODataPayloadKind payloadKind)
        {
            ExceptionUtils.CheckArgumentNotNull(messageWriter, "messageWriter");

            if (payloadKind == ODataPayloadKind.Unsupported)
            {
                throw new ArgumentException(Strings.ODataMessageWriter_CannotSetHeadersWithInvalidPayloadKind(payloadKind), "payloadKind");
            }

            return messageWriter.SetHeaders(payloadKind);
        }
        /// <summary>
        /// Verifies that the result of the test (the message reader) is what the test expected.
        /// </summary>
        /// <param name="messageReader">The message reader which is the result of the test. This method should use it to read the results
        /// of the parsing and verify those.</param>
        /// <param name="payloadKind">The payload kind specified in the test descriptor.</param>
        /// <param name="testConfiguration">The test configuration to use.</param>
        public override void VerifyResult(
            ODataMessageReaderTestWrapper messageReader,
            ODataPayloadKind payloadKind,
            ReaderTestConfiguration testConfiguration)
        {
            // First compare the payload kind detection results.
            IEnumerable<ODataPayloadKindDetectionResult> actualDetectionResults = messageReader.DetectPayloadKind();
            this.VerifyPayloadKindDetectionResult(actualDetectionResults);

            // Then try to read the message as the detected kind if requested
            if (this.ReadDetectedPayloads)
            {
                bool firstResult = true;
                foreach (PayloadKindDetectionResult result in this.ExpectedDetectionResults)
                {
                    if (firstResult)
                    {
                        // For the first result use the existing message reader
                        firstResult = false;
                    }
                    else
                    {
                        // For all subsequent results we need to reset the test stream and create a new message reader
                        // over it.
                        this.TestMessage.Reset();
                        messageReader = TestReaderUtils.CreateMessageReader(this.TestMessage, result.Model, testConfiguration);

                        // Detect the payload kinds again and make sure we can also read the subsequent payload kinds
                        // immediately after detection.
                        actualDetectionResults = messageReader.DetectPayloadKind();
                        this.VerifyPayloadKindDetectionResult(actualDetectionResults);
                    }

                    TestExceptionUtils.ExpectedException(
                        this.settings.Assert,
                        () =>
                            {
                                using (messageReader)
                                {
                                    this.settings.MessageToObjectModelReader.ReadMessage(
                                        messageReader,
                                        result.PayloadKind,
                                        result.Model,
                                        new PayloadReaderTestDescriptor.ReaderMetadata(result.ExpectedType),
                                        /*expectedBatchPayload*/ null,
                                        testConfiguration);
                                }
                            },
                        result.ExpectedException,
                        this.settings.ExceptionVerifier);
                }
            }
        }
Пример #16
0
        public override IEnumerable<ODataMediaTypeFormat> GetMediaTypeFormats(ODataPayloadKind payloadKind)
        {
            if (payloadKind == ODataPayloadKind.Property)
            {
                return VCardMediaTypeResolver.Instance.GetMediaTypeFormats(payloadKind);
            }
            else if (payloadKind == ODataPayloadKind.Entry || payloadKind == ODataPayloadKind.Feed)
            {
                return CsvMediaTypeResolver.Instance.GetMediaTypeFormats(payloadKind);
            }

            return base.GetMediaTypeFormats(payloadKind);
        }
        /// <summary>
        /// Verifies that the result of the test is what the test expected.
        /// </summary>
        /// <param name="stream">The stream after writing the message content. This method should use it 
        /// to read the message content and verify it.</param>
        /// <param name="payloadKind">The payload kind specified in the test descriptor.</param>
        /// <param name="testConfiguration">The test configuration to use.</param>
        public override void VerifyResult(
            TestMessage message,
            ODataPayloadKind payloadKind,
            WriterTestConfiguration testConfiguration,
            BaselineLogger logger)
        {
            // Get observed payload
#if !SILVERLIGHT
            var observed = TestWriterUtils.ReadToString(message);

            if (logger != null) logger.LogPayload(TestWriterUtils.BaseLineFixup(observed));
#endif
            // TODO: Handle SILVERLIGHT

        }
        /// <summary>
        /// Verifies the result of the write-read.
        /// </summary>
        /// <param name="message">The test message is not used but is required to keep the method signature the same.</param>
        /// <param name="payloadKind">The payload kind is not used but is required to keep the method signature the same.</param>
        /// <param name="testConfiguration">The test configuration is used for some fixups.</param>
        public override void VerifyResult(TestMessage message, ODataPayloadKind payloadKind, WriterTestConfiguration testConfiguration, BaselineLogger logger=null)
        {
            //TODO: Use Logger to verify result, right now this change is only to unblock writer testcase checkin

            Debug.Assert(ObservedElement != null, "ObservedElement not provided");
            // Fixup the expected and get the content type
            ODataPayloadElement expected = this.ExpectedPayload.DeepCopy();
            ODataPayloadElement observed = this.ObservedElement.DeepCopy();

            observed.Accept(new RemoveTypeNameAnnotationFromComplexInCollection());
            expected.Accept(new ReorderProperties());
            expected.Accept(new RemoveComplexWithNoProperties());
            
            // Compare
            this.settings.PayloadElementComparer.Compare(expected, observed);
        }
        /// <summary>
        /// Verifies that the result of the test (the message reader) is what the test expected.
        /// </summary>
        /// <param name="messageReader">The message reader which is the result of the test. This method should use it to read the results
        /// of the parsing and verify those.</param>
        /// <param name="payloadKind">The payload kind specified in the test descriptor.</param>
        /// <param name="testConfiguration">The test configuration to use.</param>
        public override void VerifyResult(
            ODataMessageReaderTestWrapper messageReader,
            ODataPayloadKind payloadKind, 
            ReaderTestConfiguration testConfiguration)
        {
            this.settings.Assert.IsTrue(payloadKind == ODataPayloadKind.MetadataDocument, "Only metadata payload kind is supported.");

            object metadata = this.settings.MessageToObjectModelReader.ReadMessage(
                messageReader, 
                payloadKind,
                /*payloadModel*/ null,
                PayloadReaderTestDescriptor.ReaderMetadata.None,
                /*expectedBatchPayload*/ null,
                testConfiguration);
            IEdmModel actualModel = metadata as IEdmModel;
            this.settings.Assert.IsTrue(metadata != null && actualModel != null, "Expected a non-null model to be read.");
        }
 public static bool IsDefined(ODataPayloadKind payloadKind)
 {
     return payloadKind == ODataPayloadKind.Batch
         || payloadKind == ODataPayloadKind.BinaryValue
         || payloadKind == ODataPayloadKind.Collection
         || payloadKind == ODataPayloadKind.EntityReferenceLink
         || payloadKind == ODataPayloadKind.EntityReferenceLinks
         || payloadKind == ODataPayloadKind.Entry
         || payloadKind == ODataPayloadKind.Error
         || payloadKind == ODataPayloadKind.Feed
         || payloadKind == ODataPayloadKind.MetadataDocument
         || payloadKind == ODataPayloadKind.Parameter
         || payloadKind == ODataPayloadKind.Property
         || payloadKind == ODataPayloadKind.ServiceDocument
         || payloadKind == ODataPayloadKind.Value
         || payloadKind == ODataPayloadKind.Unsupported;
 }
        /// <summary>
        /// Verifies that the result of the test is what the test expected.
        /// </summary>
        /// <param name="stream">The stream after writing the message content. This method should use it 
        /// to read the message content and verify it.</param>
        /// <param name="payloadKind">The payload kind specified in the test descriptor.</param>
        /// <param name="testConfiguration">The test configuration to use.</param>
        public override void VerifyResult(
            TestMessage message,
            ODataPayloadKind payloadKind, 
            WriterTestConfiguration testConfiguration,
            BaselineLogger logger)
        {
            this.settings.Assert.IsTrue(payloadKind == ODataPayloadKind.MetadataDocument, "Only metadata payload kind is supported.");

            // read the message content using the Taupo infrastructure
            ExceptionUtilities.CheckArgumentNotNull(message.TestStream, "stream != null");
#if !SILVERLIGHT
            var observed = TestWriterUtils.ReadToString(message);

            if (logger != null) logger.LogPayload(TestWriterUtils.BaseLineFixup(observed));
#endif
            // TODO: Handle SILVERLIGHT

        }
Пример #22
0
 private ODataRawInputContext(ODataFormat format, System.IO.Stream messageStream, Encoding encoding, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, bool readingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver, ODataPayloadKind readerPayloadKind) : base(format, messageReaderSettings, version, readingResponse, synchronous, model, urlResolver)
 {
     ExceptionUtils.CheckArgumentNotNull<ODataFormat>(format, "format");
     ExceptionUtils.CheckArgumentNotNull<ODataMessageReaderSettings>(messageReaderSettings, "messageReaderSettings");
     try
     {
         this.stream = messageStream;
         this.encoding = encoding;
         this.readerPayloadKind = readerPayloadKind;
     }
     catch (Exception exception)
     {
         if (ExceptionUtils.IsCatchableExceptionType(exception) && (messageStream != null))
         {
             messageStream.Dispose();
         }
         throw;
     }
 }
        /// <summary>
        /// Verifies that the result of the test (the message reader) is what the test expected.
        /// </summary>
        /// <param name="messageReader">The message reader which is the result of the test. This method should use it to read the results
        /// of the parsing and verify those.</param>
        /// <param name="payloadKind">The payload kind specified in the test descriptor.</param>
        /// <param name="testConfiguration">The test configuration to use.</param>
        public override void VerifyResult(
            ODataMessageReaderTestWrapper messageReader,
            ODataPayloadKind payloadKind,
            ReaderTestConfiguration testConfiguration)
        {
            object odataObject = this.settings.MessageToObjectModelReader.ReadMessage(
                messageReader,
                ODataPayloadKind.Batch,
                this.PayloadModel,
                PayloadReaderTestDescriptor.ReaderMetadata.None,
                this.ExpectedBatchPayload, 
                testConfiguration);

            // only compare the payloads if the expected payload is not 'null'; null indicates to skip the comparison
            if (this.ExpectedBatchPayload != null)
            {
                ODataPayloadElement actualPayloadElement = this.settings.ObjectModelToPayloadElementConverter.Convert(odataObject, !testConfiguration.IsRequest);
                this.settings.BatchComparer.CompareBatchPayload(this.ExpectedBatchPayload, actualPayloadElement);
            }
        }
        /// <summary>
        /// Write payload kind to message.
        /// </summary>
        /// <param name="messageWriter">Message writer to write payload to.</param>
        /// <param name="payloadKind">The kind of payload we are writing.</param>
        /// <param name="payload">The payload to write.</param>
        /// <param name="functionImport">Function import whose parameters are to be written when the payload kind is Parameters.</param>
        /// <returns>The object read after writing.</returns>
        public ODataItem WriteMessage(ODataMessageWriterTestWrapper messageWriter, ODataMessageReaderTestWrapper messageReader, ODataPayloadKind payloadKind, object payload, IEdmOperationImport functionImport = null)
        {
            ExceptionUtilities.CheckArgumentNotNull(messageWriter, "messageWriter");
            ExceptionUtilities.CheckArgumentNotNull(messageReader, "messageReader");

            switch (payloadKind)
            {
                case ODataPayloadKind.Feed:
                    this.WriteTopLevelFeed(messageWriter, messageReader, (ODataFeed)payload);
                    break;
                case ODataPayloadKind.Entry:
                    this.WriteTopLevelEntry(messageWriter, messageReader, (ODataEntry)payload);
                    break;
                default:
                    ExceptionUtilities.Assert(false, "The payload kind '{0}' is not yet supported by ObjectModelWriteReadStreamer.", payloadKind);
                    break;
            }

            return readItems.SingleOrDefault();
        }
        public void StreamMessage(ODataMessageReaderTestWrapper reader, ODataMessageWriterTestWrapper writer, ODataPayloadKind payloadKind, WriterTestConfiguration config)
        {
            ExceptionUtilities.CheckArgumentNotNull(reader, "reader is required");
            ExceptionUtilities.CheckArgumentNotNull(writer, "writer is required");
            ExceptionUtilities.CheckArgumentNotNull(payloadKind, "payloadKind is required");
            ExceptionUtilities.CheckArgumentNotNull(config, "config is required");

            this.testConfiguration = config;

            switch(payloadKind)
            {
                case ODataPayloadKind.Entry:
                    this.StartRead(reader.CreateODataEntryReader(), writer.CreateODataEntryWriter());
                    break;

                case ODataPayloadKind.Feed:
                    this.StartRead(reader.CreateODataFeedReader(), writer.CreateODataFeedWriter());
                    break;
                default:
                    throw new NotSupportedException("ObjectModelReadWriteStreamer currently supports only feed and entry");
            };
        }
Пример #26
0
        public override IEnumerable<ODataMediaTypeFormat> GetMediaTypeFormats(ODataPayloadKind payloadKind)
        {
            var payloadFormats = base.GetMediaTypeFormats(payloadKind);

            if (payloadKind == ODataPayloadKind.Property)
            {
                payloadFormats = payloadFormats.Concat(vcardFormats);
            }

#if ENABLE_AVRO
            if (payloadKind == ODataPayloadKind.Feed
                || payloadKind == ODataPayloadKind.Entry
                || payloadKind == ODataPayloadKind.Property
                || payloadKind == ODataPayloadKind.Collection
                || payloadKind == ODataPayloadKind.Parameter
                || payloadKind == ODataPayloadKind.Error)
            {
                payloadFormats = payloadFormats.Concat(avroFormats);
            }
#endif

            return payloadFormats;
        }
Пример #27
0
 private void MaterializeTest(HttpStatusCode statusCode, ODataPayloadKind payloadKind)
 {
     var uri = new Uri("http://any");
     var context = new DataServiceContext();
     var requestInfo = new RequestInfo(context);
     var responseInfo = new ResponseInfo(requestInfo, MergeOption.OverwriteChanges);
     var queryComponents = new QueryComponents(uri, new Version(4, 0), typeof(Product), null, null);
     var responseMessage = new HttpWebResponseMessage(
         new HeaderCollection(),
         (int)statusCode,
         () => new MemoryStream());
     var materialize = DataServiceRequest.Materialize(
         responseInfo,
         queryComponents,
         null,
         "application/json",
         responseMessage,
         payloadKind);
     Assert.IsNull(materialize.Context);
     Assert.IsNull(materialize.Current);
     var enumerable = materialize.Cast<object>();
     Assert.AreEqual(0, enumerable.Count());
 }
Пример #28
0
 private void CheckForNavigationLinkWithContent(ODataPayloadKind contentPayloadKind)
 {
     Scope currentScope = this.CurrentScope;
     if ((currentScope.State == WriterState.NavigationLink) || (currentScope.State == WriterState.NavigationLinkWithContent))
     {
         Action action = null;
         ODataNavigationLink currentNavigationLink = (ODataNavigationLink) currentScope.Item;
         IEdmType navigationPropertyType = null;
         this.InterceptException(delegate {
             navigationPropertyType = WriterValidationUtils.ValidateNavigationLink(currentNavigationLink, this.ParentEntryEntityType, new ODataPayloadKind?(contentPayloadKind));
             ((NavigationLinkScope) this.CurrentScope).NavigationPropertyType = navigationPropertyType;
         });
         if (currentScope.State != WriterState.NavigationLinkWithContent)
         {
             this.PromoteNavigationLinkScope();
             if (!this.SkipWriting)
             {
                 if (action == null)
                 {
                     action = delegate {
                         this.DuplicatePropertyNamesChecker.CheckForDuplicatePropertyNames(currentNavigationLink, contentPayloadKind != ODataPayloadKind.EntityReferenceLink, new bool?(contentPayloadKind == ODataPayloadKind.Feed));
                         this.StartNavigationLinkWithContent(currentNavigationLink);
                     };
                 }
                 this.InterceptException(action);
             }
         }
         else if (this.outputContext.WritingResponse || (currentNavigationLink.IsCollection != true))
         {
             this.ThrowODataException(Microsoft.Data.OData.Strings.ODataWriterCore_MultipleItemsInNavigationLinkContent, currentNavigationLink);
         }
     }
     else if (contentPayloadKind == ODataPayloadKind.EntityReferenceLink)
     {
         this.ThrowODataException(Microsoft.Data.OData.Strings.ODataWriterCore_EntityReferenceLinkWithoutNavigationLink, null);
     }
 }
Пример #29
0
 /// <summary>
 /// Creates an exception which reports that the specified payload kind if not support by this format.
 /// </summary>
 /// <param name="payloadKind">The payload kind which is not supported.</param>
 /// <returns>An exception to throw.</returns>
 private ODataException CreatePayloadKindNotSupportedException(ODataPayloadKind payloadKind)
 {
     return(new ODataException(Strings.ODataInputContext_UnsupportedPayloadKindForFormat(this.format.ToString(), payloadKind.ToString())));
 }
Пример #30
0
        /// <summary>
        /// Set the default content type header for a message of the given payload kind.
        /// </summary>
        /// <param name="testMessage">The test message to set the Content-Type header on.</param>
        /// <param name="format">The format of the message.</param>
        /// <param name="payloadKind">The payload kind for which to determine and set the content type.</param>
        public static void SetContentType(this TestMessage testMessage, ODataFormat format, ODataPayloadKind payloadKind)
        {
            string contentType = TestMediaTypeUtils.GetDefaultContentType(payloadKind, format);

            testMessage.SetHeader(ODataConstants.ContentTypeHeader, contentType);
        }
Пример #31
0
        /// <summary>
        /// Constructs an ODataSerializer that can generate OData payload of the specified kind.
        /// </summary>
        /// <param name="payloadKind">The kind of OData payload that this serializer generates.</param>
        protected ODataSerializer(ODataPayloadKind payloadKind)
        {
            ODataPayloadKindHelper.Validate(payloadKind, "payloadKind");

            ODataPayloadKind = payloadKind;
        }
Пример #32
0
 internal static Task<ODataInputContext> CreateAsync(ODataFormat format, ODataMessage message, Encoding encoding, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, bool readingResponse, IEdmModel model, IODataUrlResolver urlResolver, ODataPayloadKind readerPayloadKind)
 {
     return message.GetStreamAsync().FollowOnSuccessWith<System.IO.Stream, ODataInputContext>(streamTask => new ODataRawInputContext(format, streamTask.Result, encoding, messageReaderSettings, version, readingResponse, false, model, urlResolver, readerPayloadKind));
 }
Пример #33
0
        /// <summary>
        /// Get the supported media types for a payload kind.
        /// </summary>
        /// <param name="kind">The <see cref="ODataPayloadKind"/> to get the supported media types for.</param>
        /// <param name="includeApplicationJson">true if application/json should be included as supported media type (for reading versions &lt; V3).</param>
        /// <param name="includeApplicationJsonLight">true if JsonLight media types should be included.</param>
        /// <returns>The string concatenating all supported media types for <paramref name="kind"/>.</returns>
        public static string GetSupportedMediaTypes(ODataPayloadKind kind, bool includeApplicationJson = true, bool includeApplicationJsonLight = true)
        {
            StringBuilder builder         = new StringBuilder();
            bool          hasTailingComma = false;

            // Add the JSON media types to the supported payload kinds
            switch (kind)
            {
            case ODataPayloadKind.ResourceSet:
            case ODataPayloadKind.Resource:
            case ODataPayloadKind.Property:
            case ODataPayloadKind.Collection:
            case ODataPayloadKind.EntityReferenceLink:
            case ODataPayloadKind.EntityReferenceLinks:
            case ODataPayloadKind.Error:
            case ODataPayloadKind.ServiceDocument:
            case ODataPayloadKind.Parameter:
                AddJsonMediaTypes(includeApplicationJson, includeApplicationJsonLight, builder);
                break;

            default:
                break;
            }

            switch (kind)
            {
            case ODataPayloadKind.ResourceSet:
            case ODataPayloadKind.EntityReferenceLinks:
                break;

            case ODataPayloadKind.Resource:
                break;

            case ODataPayloadKind.Property:
                break;

            case ODataPayloadKind.Collection:
                break;

            case ODataPayloadKind.Value:
                builder.Append("text/plain");
                break;

            case ODataPayloadKind.BinaryValue:
                builder.Append("application/octet-stream");
                break;

            case ODataPayloadKind.EntityReferenceLink:
                break;

            case ODataPayloadKind.Error:
                break;

            case ODataPayloadKind.ServiceDocument:
                break;

            case ODataPayloadKind.Batch:
                builder.Append("multipart/mixed, ");
                AddJsonMediaTypes(includeApplicationJson, includeApplicationJsonLight, builder);
                hasTailingComma = true;
                break;

            case ODataPayloadKind.MetadataDocument:
                break;

            case ODataPayloadKind.Parameter:
                builder.Append(string.Empty);
                break;

            case ODataPayloadKind.Unsupported:
            default:
                throw new NotSupportedException("Unsupported payload kind found: " + kind.ToString());
            }

            return(hasTailingComma
                    ? builder.ToString(0, builder.Length - 1)
                    : builder.ToString());
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="payloadKind">The detected payload kind.</param>
 /// <param name="format">The format for the detected payload kind.</param>
 internal ODataPayloadKindDetectionResult(ODataPayloadKind payloadKind, ODataFormat format)
 {
     DebugUtils.CheckNoExternalCallers();
     this.payloadKind = payloadKind;
     this.format      = format;
 }
Пример #35
0
        private static bool IgnoreTestCase(ODataPayloadKind payloadKind, ReaderTestConfiguration testConfiguration)
        {
            // TODO: enable unsupported payload kinds when implemented
            if (payloadKind == ODataPayloadKind.MetadataDocument)
            {
                return(true);
            }

            // ignore some payloads in requests since they are not allowed
            if (testConfiguration.IsRequest)
            {
                if (payloadKind == ODataPayloadKind.ServiceDocument || payloadKind == ODataPayloadKind.Error || payloadKind == ODataPayloadKind.EntityReferenceLinks)
                {
                    // not allowed in requests
                    return(true);
                }
            }
            else
            {
                if (payloadKind == ODataPayloadKind.Parameter)
                {
                    // not allowed in responses
                    return(true);
                }
            }

            ODataFormat format = testConfiguration.Format;

            // ignore some payloads in some formats
            switch (payloadKind)
            {
            case ODataPayloadKind.Feed:
                return(format == null);

            case ODataPayloadKind.Entry:
                return(format == null);

            case ODataPayloadKind.Property:
                return(format == null);

            case ODataPayloadKind.EntityReferenceLink:
                return(format == null);

            case ODataPayloadKind.EntityReferenceLinks:
                return(format == null);

            case ODataPayloadKind.Value:
                return(format != null);

            case ODataPayloadKind.BinaryValue:
                return(format != null);

            case ODataPayloadKind.Collection:
                return(format == null);

            case ODataPayloadKind.ServiceDocument:
                return(format == null);

            case ODataPayloadKind.MetadataDocument:
                return(format != null);

            case ODataPayloadKind.Error:
                return(format == null);

            case ODataPayloadKind.Batch:
                return(format != null);

            case ODataPayloadKind.Parameter:
                return(format != ODataFormat.Json);

            case ODataPayloadKind.Unsupported:      // fall through
            default:
                return(true);
            }
        }
Пример #36
0
        /// <summary>
        /// Creates an <see cref="ODataMaterializer"/> for a response.
        /// </summary>
        /// <param name="responseMessage">The response message.</param>
        /// <param name="responseInfo">The response context.</param>
        /// <param name="materializerType">The type to materialize.</param>
        /// <param name="queryComponents">The query components for the request.</param>
        /// <param name="plan">The projection plan.</param>
        /// <param name="payloadKind">expected payload kind.</param>
        /// <returns>A materializer specialized for the given response.</returns>
        public static ODataMaterializer CreateMaterializerForMessage(
            IODataResponseMessage responseMessage,
            ResponseInfo responseInfo,
            Type materializerType,
            QueryComponents queryComponents,
            ProjectionPlan plan,
            ODataPayloadKind payloadKind)
        {
            ODataMessageReader messageReader = CreateODataMessageReader(responseMessage, responseInfo, ref payloadKind);

            ODataMaterializer result;
            IEdmType          edmType = null;

            try
            {
                ODataMaterializerContext materializerContext = new ODataMaterializerContext(responseInfo);

                // Since in V1/V2, astoria client allowed Execute<object> and depended on the typeresolver or the wire type name
                // to get the clr type to materialize. Hence if we see the materializer type as object, we should set the edmtype
                // to null, since there is no expected type.
                if (materializerType != typeof(System.Object))
                {
                    edmType = responseInfo.TypeResolver.ResolveExpectedTypeForReading(materializerType);
                }

                if (payloadKind == ODataPayloadKind.Property && edmType != null)
                {
                    if (edmType.TypeKind.IsStructured())
                    {
                        payloadKind = ODataPayloadKind.Resource;
                    }
                    else if (edmType.TypeKind == EdmTypeKind.Collection && (edmType as IEdmCollectionType).ElementType.IsStructured())
                    {
                        payloadKind = ODataPayloadKind.ResourceSet;
                    }
                }

                if (payloadKind == ODataPayloadKind.Resource || payloadKind == ODataPayloadKind.ResourceSet)
                {
                    // In V1/V2, we allowed System.Object type to be allowed to pass to ExecuteQuery.
                    // Hence we need to explicitly check for System.Object to allow this
                    if (edmType != null && !edmType.TypeKind.IsStructured())
                    {
                        throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidNonEntityType(materializerType.FullName));
                    }

                    ODataReaderWrapper       reader = ODataReaderWrapper.Create(messageReader, payloadKind, edmType, responseInfo.ResponsePipeline);
                    EntityTrackingAdapter    entityTrackingAdapter    = new EntityTrackingAdapter(responseInfo.EntityTracker, responseInfo.MergeOption, responseInfo.Model, responseInfo.Context);
                    LoadPropertyResponseInfo loadPropertyResponseInfo = responseInfo as LoadPropertyResponseInfo;

                    if (loadPropertyResponseInfo != null)
                    {
                        result = new ODataLoadNavigationPropertyMaterializer(
                            messageReader,
                            reader,
                            materializerContext,
                            entityTrackingAdapter,
                            queryComponents,
                            materializerType,
                            plan,
                            loadPropertyResponseInfo);
                    }
                    else
                    {
                        result = new ODataReaderEntityMaterializer(
                            messageReader,
                            reader,
                            materializerContext,
                            entityTrackingAdapter,
                            queryComponents,
                            materializerType,
                            plan);
                    }
                }
                else
                {
                    switch (payloadKind)
                    {
                    case ODataPayloadKind.Value:
                        result = new ODataValueMaterializer(messageReader, materializerContext, materializerType, queryComponents.SingleResult);
                        break;

                    case ODataPayloadKind.Collection:
                        result = new ODataCollectionMaterializer(messageReader, materializerContext, materializerType, queryComponents.SingleResult);
                        break;

                    case ODataPayloadKind.Property:
                    case ODataPayloadKind.IndividualProperty:
                        // Top level properties cannot be of entity type.
                        if (edmType != null && (edmType.TypeKind == EdmTypeKind.Entity || edmType.TypeKind == EdmTypeKind.Complex))
                        {
                            throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidEntityType(materializerType.FullName));
                        }

                        result = new ODataPropertyMaterializer(messageReader, materializerContext, materializerType, queryComponents.SingleResult);
                        break;

                    case ODataPayloadKind.EntityReferenceLinks:
                    case ODataPayloadKind.EntityReferenceLink:
                        result = new ODataLinksMaterializer(messageReader, materializerContext, materializerType, queryComponents.SingleResult);
                        break;

                    case ODataPayloadKind.Error:
                        var odataError = messageReader.ReadError();
                        throw new ODataErrorException(odataError.Message, odataError);

                    default:
                        throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidResponsePayload(XmlConstants.DataWebNamespace));
                    }
                }

                return(result);
            }
            catch (Exception ex)
            {
                if (CommonUtil.IsCatchableExceptionType(ex))
                {
                    // Dispose the message reader in all error scenarios.
                    messageReader.Dispose();
                }

                throw;
            }
        }
Пример #37
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="resolver">The media type resolver to use.</param>
 /// <param name="payloadKind">Kind of the payload.</param>
 /// <param name="contentTypeName">Name of content type.</param>
 public MatchInfoCacheKey(ODataMediaTypeResolver resolver, ODataPayloadKind payloadKind, string contentTypeName)
 {
     this.MediaTypeResolver = resolver;
     this.PayloadKind       = payloadKind;
     this.ContentTypeName   = contentTypeName;
 }
 /// <summary>
 /// Sets the content-type and data service version headers on the message used by the message writer.
 /// This method can be called if it is important to set all the message headers before calling any of the
 /// write methods.
 /// If it is sufficient to set the headers when the write methods on the message writer
 /// are called, you don't have to call this method and setting the headers will happen automatically.
 /// </summary>
 /// <param name="payloadKind">The kind of payload to be written with the message writer.</param>
 /// <returns>The <see cref="ODataFormat"/> used for the specified <paramref name="payloadKind"/>.</returns>
 public ODataFormat SetHeadersForPayload(ODataPayloadKind payloadKind)
 {
     return(ODataUtils.SetHeadersForPayload(this.messageWriter, payloadKind));
 }
 protected ODataEntryDeserializer(IEdmTypeReference edmType, ODataPayloadKind payloadKind, ODataDeserializerProvider deserializerProvider)
     : this(edmType, payloadKind)
 {
     DeserializerProvider = deserializerProvider;
 }
Пример #40
0
        /// <summary>Sets the content-type and OData-Version headers on the message used by the message writer.</summary>
        /// <returns>The content-type and OData-Version headers on the message used by the message writer.</returns>
        /// <param name="messageWriter">The message writer to set the headers for.</param>
        /// <param name="payloadKind">The kind of payload to be written with the message writer.</param>
        /// <remarks>
        /// This method can be called if it is important to set all the message headers before calling any of the
        /// write methods on the <paramref name="messageWriter"/>.
        /// If it is sufficient to set the headers when the write methods on the <paramref name="messageWriter"/>
        /// are called, you don't have to call this method and setting the headers will happen automatically.
        /// </remarks>
        public static ODataFormat SetHeadersForPayload(ODataMessageWriter messageWriter, ODataPayloadKind payloadKind)
        {
            ExceptionUtils.CheckArgumentNotNull(messageWriter, "messageWriter");

            if (payloadKind == ODataPayloadKind.Unsupported)
            {
                throw new ArgumentException(Strings.ODataMessageWriter_CannotSetHeadersWithInvalidPayloadKind(payloadKind), "payloadKind");
            }

            return(messageWriter.SetHeaders(payloadKind));
        }
        private ODataPayloadKind ParseContextUriFragment(string fragment, Func <IEdmType, string, IEdmType> clientCustomTypeResolver, bool throwIfMetadataConflict, out bool isUndeclared)
        {
            bool           hasItemSelector = false;
            ODataDeltaKind kind            = ODataDeltaKind.None;

            isUndeclared = false;

            // Deal with /$entity
            if (fragment.EndsWith(ODataConstants.ContextUriFragmentItemSelector, StringComparison.Ordinal))
            {
                hasItemSelector = true;
                fragment        = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriFragmentItemSelector.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeltaResourceSet, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.ResourceSet;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeltaResourceSet.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeletedEntry, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.DeletedEntry;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeletedEntry.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeltaLink, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.Link;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeltaLink.Length);
            }
            else if (fragment.EndsWith(ODataConstants.ContextUriDeletedLink, StringComparison.Ordinal))
            {
                kind     = ODataDeltaKind.DeletedLink;
                fragment = fragment.Substring(0, fragment.Length - ODataConstants.ContextUriDeletedLink.Length);
            }

            this.parseResult.DeltaKind = kind;

            // Deal with query option
            if (fragment.EndsWith(")", StringComparison.Ordinal))
            {
                int index = fragment.Length - 2;
                for (int rcount = 1; rcount > 0 && index > 0; --index)
                {
                    switch (fragment[index])
                    {
                    case '(':
                        rcount--;
                        break;

                    case ')':
                        rcount++;
                        break;
                    }
                }

                if (index == 0)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                string previous = fragment.Substring(0, index + 1);

                // Don't treat Collection(Edm.Type) as SelectExpand segment
                if (!previous.Equals("Collection", StringComparison.Ordinal))
                {
                    string selectExpandStr = fragment.Substring(index + 2);
                    selectExpandStr = selectExpandStr.Substring(0, selectExpandStr.Length - 1);

                    // Do not treat Key as SelectExpand segment
                    if (KeyPattern.IsMatch(selectExpandStr))
                    {
                        throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_LastSegmentIsKeySegment(UriUtils.UriToString(this.parseResult.ContextUri)));
                    }

                    this.parseResult.SelectQueryOption = ExtractSelectQueryOption(selectExpandStr);
                    fragment = previous;
                }
            }

            ODataPayloadKind detectedPayloadKind = ODataPayloadKind.Unsupported;
            EdmTypeResolver  edmTypeResolver     = new EdmTypeReaderResolver(this.model, clientCustomTypeResolver);

            if (!fragment.Contains(ODataConstants.UriSegmentSeparator) && !hasItemSelector && kind == ODataDeltaKind.None)
            {
                // Service document: no fragment
                if (fragment.Length == 0)
                {
                    detectedPayloadKind = ODataPayloadKind.ServiceDocument;
                }
                else if (fragment.Equals(ODataConstants.CollectionPrefix + "(" + ODataConstants.EntityReferenceSegmentName + ")", StringComparison.Ordinal))
                {
                    detectedPayloadKind = ODataPayloadKind.EntityReferenceLinks;
                }
                else if (fragment.Equals(ODataConstants.EntityReferenceSegmentName, StringComparison.Ordinal))
                {
                    detectedPayloadKind = ODataPayloadKind.EntityReferenceLink;
                }
                else
                {
                    var foundNavigationSource = this.model.FindDeclaredNavigationSource(fragment);

                    if (foundNavigationSource != null)
                    {
                        // Resource Set: {schema.entity-container.entity-set} or Singleton: {schema.entity-container.singleton}
                        this.parseResult.NavigationSource = foundNavigationSource;
                        this.parseResult.EdmType          = edmTypeResolver.GetElementType(foundNavigationSource);
                        detectedPayloadKind = foundNavigationSource is IEdmSingleton ? ODataPayloadKind.Resource : ODataPayloadKind.ResourceSet;
                    }
                    else
                    {
                        // Property: {schema.type} or Collection({schema.type}) where schema.type is primitive or complex.
                        detectedPayloadKind = this.ResolveType(fragment, clientCustomTypeResolver, throwIfMetadataConflict);
                        Debug.Assert(
                            this.parseResult.EdmType.TypeKind == EdmTypeKind.Primitive || this.parseResult.EdmType.TypeKind == EdmTypeKind.Enum || this.parseResult.EdmType.TypeKind == EdmTypeKind.TypeDefinition || this.parseResult.EdmType.TypeKind == EdmTypeKind.Complex || this.parseResult.EdmType.TypeKind == EdmTypeKind.Collection || this.parseResult.EdmType.TypeKind == EdmTypeKind.Entity || this.parseResult.EdmType.TypeKind == EdmTypeKind.Untyped,
                            "The first context URI segment must be a set or a non-entity type.");
                    }
                }
            }
            else
            {
                Debug.Assert(this.parseResult.MetadataDocumentUri.IsAbsoluteUri, "this.parseResult.MetadataDocumentUri.IsAbsoluteUri");

                string metadataDocumentStr = UriUtils.UriToString(this.parseResult.MetadataDocumentUri);

                if (!metadataDocumentStr.EndsWith(ODataConstants.UriMetadataSegment, StringComparison.Ordinal))
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                Uri serviceRoot = new Uri(metadataDocumentStr.Substring(0, metadataDocumentStr.Length - ODataConstants.UriMetadataSegment.Length));

                ODataUriParser odataUriParser = new ODataUriParser(this.model, serviceRoot, new Uri(serviceRoot, fragment));

                ODataPath path;
                try
                {
                    path = odataUriParser.ParsePath();
                }
                catch (ODataException)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                if (path.Count == 0)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }

                this.parseResult.Path = path;

                parseResult.NavigationSource = path.NavigationSource();
                parseResult.EdmType          = path.LastSegment.EdmType;

                ODataPathSegment lastSegment = path.TrimEndingTypeSegment().LastSegment;
                if (lastSegment is EntitySetSegment || lastSegment is NavigationPropertySegment)
                {
                    if (kind != ODataDeltaKind.None)
                    {
                        detectedPayloadKind = ODataPayloadKind.Delta;
                    }
                    else
                    {
                        detectedPayloadKind = hasItemSelector ? ODataPayloadKind.Resource : ODataPayloadKind.ResourceSet;
                    }

                    if (this.parseResult.EdmType is IEdmCollectionType)
                    {
                        var collectionTypeReference = this.parseResult.EdmType.ToTypeReference().AsCollection();
                        if (collectionTypeReference != null)
                        {
                            this.parseResult.EdmType = collectionTypeReference.ElementType().Definition;
                        }
                    }
                }
                else if (lastSegment is SingletonSegment)
                {
                    detectedPayloadKind = ODataPayloadKind.Resource;
                }
                else if (path.IsIndividualProperty())
                {
                    isUndeclared        = path.IsUndeclared();
                    detectedPayloadKind = ODataPayloadKind.Property;
                    IEdmComplexType complexType = parseResult.EdmType as IEdmComplexType;
                    if (complexType != null)
                    {
                        detectedPayloadKind = ODataPayloadKind.Resource;
                    }
                    else
                    {
                        IEdmCollectionType collectionType = parseResult.EdmType as IEdmCollectionType;

                        if (collectionType != null)
                        {
                            if (collectionType.ElementType.IsComplex())
                            {
                                this.parseResult.EdmType = collectionType.ElementType.Definition;
                                detectedPayloadKind      = ODataPayloadKind.ResourceSet;
                            }
                            else
                            {
                                detectedPayloadKind = ODataPayloadKind.Collection;
                            }
                        }
                    }
                }
                else
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidContextUrl(UriUtils.UriToString(this.parseResult.ContextUri)));
                }
            }

            return(detectedPayloadKind);
        }
 protected ODataEntryDeserializer(IEdmTypeReference edmType, ODataPayloadKind payloadKind)
     : base(edmType, payloadKind)
 {
 }
Пример #43
0
 /// <summary>
 /// Verifies that the result of the test (the message reader) is what the test expected.
 /// </summary>
 /// <param name="messageReader">The message reader which is the result of the test. This method should use it to read the results
 /// of the parsing and verify those.</param>
 /// <param name="payloadKind">The payload kind specified in the test descriptor.</param>
 /// <param name="testConfiguration">The test configuration to use.</param>
 public abstract void VerifyResult(
     ODataMessageReaderTestWrapper messageReader,
     ODataPayloadKind payloadKind,
     ReaderTestConfiguration testConfiguration);
Пример #44
0
        /// <summary>
        /// Given the Accept and the Accept-Charset headers of the request message computes the media type, encoding and <see cref="ODataFormat"/>
        /// to be used for the response message.
        /// </summary>
        /// <param name="settings">The message writer settings to use for serializing the response payload.</param>
        /// <param name="payloadKind">The kind of payload to be serialized as part of the response message.</param>
        /// <param name="mediaTypeResolver">The media type resolver to use when interpreting the content type.</param>
        /// <param name="mediaType">The media type to be used in the response message.</param>
        /// <param name="encoding">The encoding to be used in the response message.</param>
        /// <returns>The <see cref="ODataFormat"/> used when serializing the response.</returns>
        internal static ODataFormat GetContentTypeFromSettings(
            ODataMessageWriterSettings settings,
            ODataPayloadKind payloadKind,
            ODataMediaTypeResolver mediaTypeResolver,
            out ODataMediaType mediaType,
            out Encoding encoding)
        {
            Debug.Assert(settings != null, "settings != null");

            // compute format, media type and encoding
            ODataFormat format;

            // get the supported and default media types for the specified payload kind
            IList <ODataMediaTypeFormat> supportedMediaTypes = mediaTypeResolver.GetMediaTypeFormats(payloadKind).ToList();

            if (supportedMediaTypes == null || supportedMediaTypes.Count == 0)
            {
                throw new ODataContentTypeException(Strings.MediaTypeUtils_DidNotFindMatchingMediaType(null, settings.AcceptableMediaTypes));
            }

            if (settings.UseFormat == true)
            {
                Debug.Assert(settings.AcceptableMediaTypes == null, "settings.AcceptableMediaTypes == null");
                Debug.Assert(settings.AcceptableCharsets == null, "settings.AcceptableCharsets == null");

                mediaType = GetDefaultMediaType(supportedMediaTypes, settings.Format, out format);

                // NOTE the default media types don't have any parameters (in particular no 'charset' parameters)
                encoding = mediaType.SelectEncoding();
            }
            else
            {
                // parse the accept header into its parts
                IList <KeyValuePair <ODataMediaType, string> > specifiedTypes = HttpUtils.MediaTypesFromString(settings.AcceptableMediaTypes);

                // Starting in V3 we replace all occurrences of application/json with application/json;odata.metadata=minimal
                // before handing the acceptable media types to the conneg code. This is necessary because for an accept
                // header 'application/json, we want to the result to be 'application/json;odata.metadata=minimal'
                ConvertApplicationJsonInAcceptableMediaTypes(specifiedTypes);

                ODataMediaTypeFormat selectedMediaTypeWithFormat;
                string specifiedCharset = null;
                if (specifiedTypes == null || specifiedTypes.Count == 0)
                {
                    selectedMediaTypeWithFormat = supportedMediaTypes[0];
                }
                else
                {
                    // match the specified media types against the supported/default ones and get the format
                    MediaTypeMatchInfo matchInfo = MatchMediaTypes(specifiedTypes.Select(kvp => kvp.Key), supportedMediaTypes.Select(smt => smt.MediaType).ToArray());
                    if (matchInfo == null)
                    {
                        // We're calling the ToArray here since not all platforms support the string.Join which takes IEnumerable.
                        string supportedTypesAsString = String.Join(", ", supportedMediaTypes.Select(mt => mt.MediaType.ToText()).ToArray());
                        throw new ODataContentTypeException(Strings.MediaTypeUtils_DidNotFindMatchingMediaType(supportedTypesAsString, settings.AcceptableMediaTypes));
                    }

                    selectedMediaTypeWithFormat = supportedMediaTypes[matchInfo.TargetTypeIndex];
                    specifiedCharset            = specifiedTypes[matchInfo.SourceTypeIndex].Value;
                }

                format    = selectedMediaTypeWithFormat.Format;
                mediaType = selectedMediaTypeWithFormat.MediaType;

                // If a charset was specified with the accept header, consider it for the encoding
                string acceptableCharsets = settings.AcceptableCharsets;
                if (specifiedCharset != null)
                {
                    acceptableCharsets = acceptableCharsets == null ? specifiedCharset : specifiedCharset + "," + acceptableCharsets;
                }

                encoding = GetEncoding(acceptableCharsets, payloadKind, mediaType, /*useDefaultEncoding*/ true);
            }

            return(format);
        }
Пример #45
0
        /// <summary>
        /// Applies the model and validates the context URI against it.
        /// </summary>
        /// <param name="expectedPayloadKind">The payload kind we expect the context URI to conform to.</param>
        /// <param name="clientCustomTypeResolver">The function of client cuetom type resolver.</param>
        private void ParseContextUri(ODataPayloadKind expectedPayloadKind, Func <IEdmType, string, IEdmType> clientCustomTypeResolver)
        {
            bool             isUndeclared        = false;
            ODataPayloadKind detectedPayloadKind = this.ParseContextUriFragment(this.parseResult.Fragment, clientCustomTypeResolver, out isUndeclared);

            // unsupported payload kind indicates that this is during payload kind detection, so we should not fail.
            bool detectedPayloadKindMatchesExpectation = detectedPayloadKind == expectedPayloadKind || expectedPayloadKind == ODataPayloadKind.Unsupported;

            if (detectedPayloadKind == ODataPayloadKind.ResourceSet && this.parseResult.EdmType.IsODataComplexTypeKind())
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.ResourceSet, ODataPayloadKind.Property, ODataPayloadKind.Collection };

                if (expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Collection)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Resource && this.parseResult.EdmType.IsODataComplexTypeKind())
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Resource, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Collection)
            {
                // If the detected payload kind is 'collection' it can always also be treated as a property.
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Collection, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Resource)
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Resource, ODataPayloadKind.Delta };
                if (expectedPayloadKind == ODataPayloadKind.Delta)
                {
                    this.parseResult.DeltaKind            = ODataDeltaKind.Resource;
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Property && isUndeclared &&
                     (expectedPayloadKind == ODataPayloadKind.Resource || expectedPayloadKind == ODataPayloadKind.ResourceSet))
            {
                // for undeclared, we don't know whether it is a resource/resource set or not.
                this.parseResult.DetectedPayloadKinds = new[] { expectedPayloadKind, ODataPayloadKind.Property };
                detectedPayloadKindMatchesExpectation = true;
            }
            else
            {
                this.parseResult.DetectedPayloadKinds = new[] { detectedPayloadKind };
            }

            // If the expected and detected payload kinds don't match and we are not running payload kind detection
            // right now (payloadKind == ODataPayloadKind.Unsupported) and we did not detect a collection kind for
            // an expected property kind (which is allowed), fail.
            if (!detectedPayloadKindMatchesExpectation)
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_ContextUriDoesNotMatchExpectedPayloadKind(UriUtils.UriToString(this.parseResult.ContextUri), expectedPayloadKind.ToString()));
            }

            // NOTE: we interpret an empty select query option to mean that nothing should be projected
            //       (whereas a missing select query option means everything should be projected).
            string selectQueryOption = this.parseResult.SelectQueryOption;

            if (selectQueryOption != null)
            {
                if (detectedPayloadKind != ODataPayloadKind.ResourceSet && detectedPayloadKind != ODataPayloadKind.Resource && detectedPayloadKind != ODataPayloadKind.Delta)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidPayloadKindWithSelectQueryOption(expectedPayloadKind.ToString()));
                }
            }
        }
Пример #46
0
 internal static ODataInputContext Create(ODataFormat format, ODataMessage message, Encoding encoding, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, bool readingResponse, IEdmModel model, IODataUrlResolver urlResolver, ODataPayloadKind readerPayloadKind)
 {
     return(new ODataRawInputContext(format, message.GetStream(), encoding, messageReaderSettings, version, readingResponse, true, model, urlResolver, readerPayloadKind));
 }
Пример #47
0
        private static ODataPayloadElement CreatePayloadElement(IEdmModel model, ODataPayloadKind payloadKind, ReaderTestConfiguration testConfig)
        {
            IEdmEntitySet          citySet              = model.EntityContainer.FindEntitySet("Cities");
            IEdmEntityType         cityType             = model.EntityTypes().Single(e => e.Name == "CityType");
            IEdmProperty           cityNameProperty     = cityType.Properties().Single(e => e.Name == "Name");
            IEdmNavigationProperty policeStationNavProp = cityType.NavigationProperties().Single(e => e.Name == "PoliceStation");
            IEdmOperationImport    primitiveCollectionResultOperation = model.EntityContainer.FindOperationImports("PrimitiveCollectionResultOperation").Single();
            IEdmOperationImport    serviceOp1 = model.EntityContainer.FindOperationImports("ServiceOperation1").Single();

            bool isRequest          = testConfig.IsRequest;
            bool isJsonLightRequest = isRequest && testConfig.Format == ODataFormat.Json;

            switch (payloadKind)
            {
            case ODataPayloadKind.Feed:
            {
                return(PayloadBuilder.EntitySet().WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet));
            }

            case ODataPayloadKind.Entry:
            {
                return(PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).WithTypeAnnotation(cityType).ExpectedEntityType(cityType, citySet));
            }

            case ODataPayloadKind.Property:
                return(PayloadBuilder.PrimitiveProperty(isJsonLightRequest ? string.Empty : null, "SomeCityValue").ExpectedProperty(cityType, "Name"));

            case ODataPayloadKind.EntityReferenceLink:
                return(PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink").ExpectedNavigationProperty(citySet, cityType, "PoliceStation"));

            case ODataPayloadKind.EntityReferenceLinks:
                return(PayloadBuilder.LinkCollection().Item(PayloadBuilder.DeferredLink("http://odata.org/entityreferencelink")).ExpectedNavigationProperty((EdmEntitySet)citySet, (EdmEntityType)cityType, "CityHall"));

            case ODataPayloadKind.Value:
                return(PayloadBuilder.PrimitiveValue("PrimitiveValue"));

            case ODataPayloadKind.BinaryValue:
                return(PayloadBuilder.PrimitiveValue(new byte[] { 0, 0, 1, 1 }));

            case ODataPayloadKind.Collection:
                return(PayloadBuilder.PrimitiveCollection().CollectionName(null).ExpectedFunctionImport((EdmOperationImport)primitiveCollectionResultOperation));

            case ODataPayloadKind.ServiceDocument:
                Debug.Assert(!isRequest, "Not supported in requests.");
                return(new ServiceDocumentInstance().Workspace(PayloadBuilder.Workspace()));

            case ODataPayloadKind.MetadataDocument:
                Debug.Assert(!isRequest, "Not supported in requests.");
                throw new NotImplementedException();

            case ODataPayloadKind.Error:
                Debug.Assert(!isRequest, "Not supported in requests.");
                return(PayloadBuilder.Error("ErrorCode"));

            case ODataPayloadKind.Parameter:
                // build parameter payload based on model definition
                var parameterPayload           = new ComplexInstance(null, false);
                ODataPayloadElement a          = PayloadBuilder.PrimitiveValue(123).WithTypeAnnotation(EdmCoreModel.Instance.GetInt32(false));
                ODataPayloadElement b          = PayloadBuilder.PrimitiveValue("stringvalue").WithTypeAnnotation(EdmCoreModel.Instance.GetString(false));
                PrimitiveProperty   parametera = new PrimitiveProperty("a", "Edm.Integer", ((PrimitiveValue)a).ClrValue);
                PrimitiveProperty   parameterb = new PrimitiveProperty("b", "Edm.String", ((PrimitiveValue)b).ClrValue);
                parameterPayload.Add(parametera);
                parameterPayload.Add(parameterb);
                parameterPayload.ExpectedFunctionImport((EdmOperationImport)serviceOp1);
                return(parameterPayload);

            case ODataPayloadKind.Unsupported:      // fall through
            default:
                throw new NotSupportedException();
            }
        }
Пример #48
0
        private void DetectStartArrayPayloadKind(bool isTopLevel)
        {
            if (!isTopLevel)
            {
                this.AddPayloadKinds(new ODataPayloadKind[] { ODataPayloadKind.Property });
            }
            base.JsonReader.StartBuffering();
            try
            {
                base.JsonReader.ReadStartArray();
                switch (base.JsonReader.NodeType)
                {
                case JsonNodeType.EndArray:
                {
                    ODataPayloadKind[] kindArray2 = new ODataPayloadKind[3];
                    kindArray2[1] = ODataPayloadKind.Collection;
                    kindArray2[2] = ODataPayloadKind.EntityReferenceLinks;
                    this.AddPayloadKinds(kindArray2);
                    return;
                }

                case JsonNodeType.Property:
                    return;

                case JsonNodeType.PrimitiveValue:
                    this.AddPayloadKinds(new ODataPayloadKind[] { ODataPayloadKind.Collection });
                    return;

                case JsonNodeType.StartObject:
                    break;

                default:
                    return;
                }
                base.JsonReader.ReadStartObject();
                bool flag = false;
                int  num  = 0;
                while (base.JsonReader.NodeType == JsonNodeType.Property)
                {
                    string strB = base.JsonReader.ReadPropertyName();
                    num++;
                    if (num > 1)
                    {
                        break;
                    }
                    if ((string.CompareOrdinal("uri", strB) == 0) && (base.JsonReader.NodeType == JsonNodeType.PrimitiveValue))
                    {
                        flag = true;
                    }
                    base.JsonReader.SkipValue();
                }
                ODataPayloadKind[] payloadKinds = new ODataPayloadKind[2];
                payloadKinds[1] = ODataPayloadKind.Collection;
                this.AddPayloadKinds(payloadKinds);
                if (flag && (num == 1))
                {
                    this.AddPayloadKinds(new ODataPayloadKind[] { ODataPayloadKind.EntityReferenceLinks });
                }
            }
            finally
            {
                base.JsonReader.StopBuffering();
            }
        }
Пример #49
0
        /// <summary>
        /// Creates an <see cref="ODataMessageReader"/> for a given message and context using
        /// WCF DS client settings.
        /// </summary>
        /// <param name="responseMessage">The response message</param>
        /// <param name="responseInfo">The response context</param>
        /// <param name="payloadKind">Type of the message.</param>
        /// <returns>The message reader.</returns>
        protected static ODataMessageReader CreateODataMessageReader(IODataResponseMessage responseMessage, ResponseInfo responseInfo, ref ODataPayloadKind payloadKind)
        {
            ODataMessageReaderSettings settings = responseInfo.ReadHelper.CreateSettings();

            ODataMessageReader odataMessageReader = responseInfo.ReadHelper.CreateReader(responseMessage, settings);

            if (payloadKind == ODataPayloadKind.Unsupported)
            {
                var payloadKinds = odataMessageReader.DetectPayloadKind().ToList();

                if (payloadKinds.Count == 0)
                {
                    throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidResponsePayload(XmlConstants.DataWebNamespace));
                }

                // Pick the first payload kind detected by ODataLib and use that to parse the exception.
                // The only exception being payload with entity reference link(s). If one of the payload kinds
                // is reference links, then we need to give preference to reference link payloads.
                ODataPayloadKindDetectionResult detectionResult = payloadKinds.FirstOrDefault(k => k.PayloadKind == ODataPayloadKind.EntityReferenceLink || k.PayloadKind == ODataPayloadKind.EntityReferenceLinks);

                if (detectionResult == null)
                {
                    detectionResult = payloadKinds.First();
                }

                if (detectionResult.Format != ODataFormat.Json && detectionResult.Format != ODataFormat.RawValue)
                {
                    throw DSClient.Error.InvalidOperation(DSClient.Strings.AtomMaterializer_InvalidContentTypeEncountered(responseMessage.GetHeader(XmlConstants.HttpContentType)));
                }

                payloadKind = detectionResult.PayloadKind;
            }

            return(odataMessageReader);
        }
 protected ODataEntryDeserializer(IEdmTypeReference edmType, ODataPayloadKind payloadKind, ODataDeserializerProvider deserializerProvider)
     : base(edmType, payloadKind, deserializerProvider)
 {
 }
Пример #51
0
        /// <summary>
        /// Determine the <see cref="ODataFormat"/> to use for the given <paramref name="contentTypeName"/>. If no supported content type
        /// is found an exception is thrown.
        /// </summary>
        /// <param name="contentTypeName">The name of the content type to be checked.</param>
        /// <param name="supportedPayloadKinds">All possible kinds of payload that can be read with this content type.</param>
        /// <param name="mediaTypeResolver">The media type resolver to use when interpreting the content type.</param>
        /// <param name="mediaType">The media type parsed from the <paramref name="contentTypeName"/>.</param>
        /// <param name="encoding">The encoding from the content type or the default encoding for the <paramref name="mediaType" />.</param>
        /// <param name="selectedPayloadKind">
        /// The payload kind that was selected form the list of <paramref name="supportedPayloadKinds"/> for the
        /// specified <paramref name="contentTypeName"/>.
        /// </param>
        /// <returns>The <see cref="ODataFormat"/> for the <paramref name="contentTypeName"/>.</returns>
        internal static ODataFormat GetFormatFromContentType(string contentTypeName, ODataPayloadKind[] supportedPayloadKinds, ODataMediaTypeResolver mediaTypeResolver, out ODataMediaType mediaType, out Encoding encoding, out ODataPayloadKind selectedPayloadKind)
        {
            Debug.Assert(!supportedPayloadKinds.Contains(ODataPayloadKind.Unsupported), "!supportedPayloadKinds.Contains(ODataPayloadKind.Unsupported)");

            string charset;

            mediaType = ParseContentType(contentTypeName, out charset);

            IList <ODataMediaTypeFormat> supportedMediaTypes = null;

            for (int i = 0; i < supportedPayloadKinds.Length; ++i)
            {
                // get the supported and default media types for the current payload kind
                ODataPayloadKind supportedPayloadKind = supportedPayloadKinds[i];
                supportedMediaTypes = mediaTypeResolver.GetMediaTypeFormats(supportedPayloadKind).ToList();

                // match the specified media types against the supported/default ones
                // and get the format
                var cacheKey = new MatchInfoCacheKey(mediaTypeResolver, supportedPayloadKind, contentTypeName);
                MediaTypeMatchInfo matchInfo;

                if (!MatchInfoCache.TryGetValue(cacheKey, out matchInfo))
                {
                    matchInfo = MatchMediaTypes(supportedMediaTypes.Select(smt => smt.MediaType), new[] { mediaType });
                    MatchInfoCache.Add(cacheKey, matchInfo);
                }

                if (matchInfo != null)
                {
                    Debug.Assert(matchInfo.TargetTypeIndex == 0, "Invalid target type index detected.");
                    selectedPayloadKind = supportedPayloadKind;
                    encoding            = GetEncoding(charset, selectedPayloadKind, mediaType, /*useDefaultEncoding*/ false);
                    return(supportedMediaTypes[matchInfo.SourceTypeIndex].Format);
                }
            }

            // We're calling the ToArray here since not all platforms support the string.Join which takes IEnumerable.
            string supportedTypesAsString = String.Join(", ", supportedPayloadKinds.SelectMany(pk => mediaTypeResolver.GetMediaTypeFormats(pk).Select(mt => mt.MediaType.ToText())).ToArray());

            throw new ODataContentTypeException(Strings.MediaTypeUtils_CannotDetermineFormatFromContentType(supportedTypesAsString, contentTypeName));
        }
Пример #52
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataDeserializer"/> class.
 /// </summary>
 /// <param name="payloadKind">The kind of payload this deserializer handles.</param>
 protected ODataDeserializer(ODataPayloadKind payloadKind)
 {
     ODataPayloadKind = payloadKind;
 }
Пример #53
0
 internal static Task <ODataInputContext> CreateAsync(ODataFormat format, ODataMessage message, Encoding encoding, ODataMessageReaderSettings messageReaderSettings, ODataVersion version, bool readingResponse, IEdmModel model, IODataUrlResolver urlResolver, ODataPayloadKind readerPayloadKind)
 {
     return(message.GetStreamAsync().FollowOnSuccessWith <System.IO.Stream, ODataInputContext>(streamTask => new ODataRawInputContext(format, streamTask.Result, encoding, messageReaderSettings, version, readingResponse, false, model, urlResolver, readerPayloadKind)));
 }
Пример #54
0
 internal static MaterializeAtom Materialize(ResponseInfo responseInfo, System.Data.Services.Client.QueryComponents queryComponents, ProjectionPlan plan, string contentType, IODataResponseMessage message, ODataPayloadKind expectedPayloadKind)
 {
     if ((message.StatusCode != 0xcc) && !string.IsNullOrEmpty(contentType))
     {
         return(new MaterializeAtom(responseInfo, queryComponents, plan, message, expectedPayloadKind));
     }
     return(MaterializeAtom.EmptyResults);
 }
        public void CanReadType_ForTypeless_ReturnsExpectedResult_DependingOnODataPathAndPayloadKind(ODataPath path, ODataPayloadKind payloadKind)
        {
            // Arrange
            IEnumerable <ODataPayloadKind> allPayloadKinds = Enum.GetValues(typeof(ODataPayloadKind)).Cast <ODataPayloadKind>();
            var model   = CreateModel();
            var request = CreateFakeODataRequest(model);

            request.ODataProperties().Path = path;

            var formatterWithGivenPayload = new ODataMediaTypeFormatter(new[] { payloadKind })
            {
                Request = request
            };
            var formatterWithoutGivenPayload = new ODataMediaTypeFormatter(allPayloadKinds.Except(new[] { payloadKind }))
            {
                Request = request
            };

            // Act & Assert
            Assert.True(formatterWithGivenPayload.CanReadType(typeof(IEdmObject)));
            Assert.False(formatterWithoutGivenPayload.CanReadType(typeof(IEdmObject)));
        }
Пример #56
0
        internal MaterializeAtom(ResponseInfo responseInfo, QueryComponents queryComponents, ProjectionPlan plan, IODataResponseMessage responseMessage, ODataPayloadKind payloadKind)
        {
            Type type;

            this.responseInfo            = responseInfo;
            this.elementType             = queryComponents.LastSegmentType;
            this.MergeOptionValue        = responseInfo.MergeOption;
            this.expectingPrimitiveValue = PrimitiveType.IsKnownNullableType(this.elementType);
            Type materializerType = GetTypeForMaterializer(this.expectingPrimitiveValue, this.elementType, responseInfo.MaxProtocolVersion, out type);

            this.materializer = ODataMaterializer.CreateMaterializerForMessage(responseMessage, responseInfo, materializerType, queryComponents, plan, payloadKind);
        }
Пример #57
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ODataEdmTypeSerializer"/> class.
 /// </summary>
 /// <param name="payloadKind">The kind of OData payload that this serializer generates.</param>
 protected ODataEdmTypeSerializer(ODataPayloadKind payloadKind)
     : base(payloadKind)
 {
 }
Пример #58
0
        /// <summary>
        /// Gets the default content type for a given payload kind and format.
        /// </summary>
        /// <param name="kind">The payload kind to get the default format for.</param>
        /// <param name="format">The format from the test configuration.</param>
        /// <returns>The default content type used by the message writer.</returns>
        public static string GetDefaultContentType(ODataPayloadKind kind, ODataFormat format)
        {
            switch (kind)
            {
            case ODataPayloadKind.ResourceSet:
            case ODataPayloadKind.EntityReferenceLinks:
                if (format == ODataFormat.Json)
                {
                    return("application/json;odata.metadata=minimal;odata.streaming=true;charset=utf-8");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Resource:
                if (format == ODataFormat.Json)
                {
                    return("application/json;odata.metadata=minimal;odata.streaming=true;charset=utf-8");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Value:
                if (format == ODataFormat.RawValue || format == null)
                {
                    return("text/plain;charset=iso-8859-1");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.BinaryValue:
                if (format == ODataFormat.RawValue || format == null)
                {
                    return("application/octet-stream");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Property:                 // fall through
            case ODataPayloadKind.Collection:               // fall through
            case ODataPayloadKind.EntityReferenceLink:      // fall through
            case ODataPayloadKind.Error:                    // fall through
            case ODataPayloadKind.ServiceDocument:
                if (format == ODataFormat.Json)
                {
                    return("application/json;odata.metadata=minimal;odata.streaming=true;charset=utf-8");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Batch:
                if (format == ODataFormat.Batch || format == null)
                {
                    return("multipart/mixed");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.MetadataDocument:
                if (format == ODataFormat.Metadata || format == null)
                {
                    return("application/xml");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Parameter:
                if (format == ODataFormat.Json)
                {
                    return("application/json;odata.metadata=minimal;odata.streaming=true;charset=utf-8");
                }
                else
                {
                    throw new NotSupportedException("Unsupported format for " + kind.ToString() + ".");
                }

            case ODataPayloadKind.Unsupported:
            default:
                throw new NotSupportedException("Unsupported payload kind found: " + kind.ToString());
            }
        }
Пример #59
0
 /// <summary>
 /// Gets the supported media types and formats for the given payload kind.
 /// </summary>
 /// <param name="payloadKind">The payload kind to get media types for.</param>
 /// <returns>An array of media type / format pairs, sorted by priority.</returns>
 internal MediaTypeWithFormat[] GetMediaTypesForPayloadKind(ODataPayloadKind payloadKind)
 {
     DebugUtils.CheckNoExternalCallers(); 
     return this.mediaTypesForPayloadKind[(int)payloadKind];
 }
        /// <summary>
        /// Applies the model and validates the context URI against it.
        /// </summary>
        /// <param name="expectedPayloadKind">The payload kind we expect the context URI to conform to.</param>
        /// <param name="clientCustomTypeResolver">The function of client custom type resolver.</param>
        /// <param name="throwIfMetadataConflict">Whether to throw if a type specified in the ContextUri is not found in metadata.</param>
        private void ParseContextUri(ODataPayloadKind expectedPayloadKind, Func <IEdmType, string, IEdmType> clientCustomTypeResolver, bool throwIfMetadataConflict)
        {
            bool             isUndeclared;
            ODataPayloadKind detectedPayloadKind = this.ParseContextUriFragment(this.parseResult.Fragment, clientCustomTypeResolver, throwIfMetadataConflict, out isUndeclared);

            // unsupported payload kind indicates that this is during payload kind detection, so we should not fail.
            bool     detectedPayloadKindMatchesExpectation = detectedPayloadKind == expectedPayloadKind || expectedPayloadKind == ODataPayloadKind.Unsupported;
            IEdmType parseType = this.parseResult.EdmType;

            if (parseType != null && parseType.TypeKind == EdmTypeKind.Untyped)
            {
                if (string.Equals(parseType.FullTypeName(), ODataConstants.ContextUriFragmentUntyped, StringComparison.Ordinal))
                {
                    // Anything matches the built-in Edm.Untyped
                    this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.ResourceSet, ODataPayloadKind.Property, ODataPayloadKind.Collection, ODataPayloadKind.Resource };
                    detectedPayloadKindMatchesExpectation = true;
                }
                else if (expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Resource)
                {
                    // If we created an untyped type because the name was not resolved it can match any single value
                    this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Property, ODataPayloadKind.Resource };
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (parseType != null && parseType.TypeKind == EdmTypeKind.Collection && ((IEdmCollectionType)parseType).ElementType.TypeKind() == EdmTypeKind.Untyped)
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.ResourceSet, ODataPayloadKind.Property, ODataPayloadKind.Collection };
                if (expectedPayloadKind == ODataPayloadKind.ResourceSet || expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Collection)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.ResourceSet && parseType.IsODataComplexTypeKind())
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.ResourceSet, ODataPayloadKind.Property, ODataPayloadKind.Collection };

                if (expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Collection)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Resource && parseType.IsODataComplexTypeKind())
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Resource, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property || expectedPayloadKind == ODataPayloadKind.Delta)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Collection)
            {
                // If the detected payload kind is 'collection' it can always also be treated as a property.
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Collection, ODataPayloadKind.Property };
                if (expectedPayloadKind == ODataPayloadKind.Property)
                {
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Resource)
            {
                this.parseResult.DetectedPayloadKinds = new[] { ODataPayloadKind.Resource, ODataPayloadKind.Delta };
                if (expectedPayloadKind == ODataPayloadKind.Delta)
                {
                    this.parseResult.DeltaKind            = ODataDeltaKind.Resource;
                    detectedPayloadKindMatchesExpectation = true;
                }
            }
            else if (detectedPayloadKind == ODataPayloadKind.Property && isUndeclared &&
                     (expectedPayloadKind == ODataPayloadKind.Resource || expectedPayloadKind == ODataPayloadKind.ResourceSet))
            {
                // for undeclared, we don't know whether it is a resource/resource set or not.
                this.parseResult.DetectedPayloadKinds = new[] { expectedPayloadKind, ODataPayloadKind.Property };
                detectedPayloadKindMatchesExpectation = true;
            }
            else
            {
                this.parseResult.DetectedPayloadKinds = new[] { detectedPayloadKind };
            }

            // If the expected and detected payload kinds don't match and we are not running payload kind detection
            // right now (payloadKind == ODataPayloadKind.Unsupported) and we did not detect a collection kind for
            // an expected property kind (which is allowed), fail.
            if (!detectedPayloadKindMatchesExpectation)
            {
                throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_ContextUriDoesNotMatchExpectedPayloadKind(UriUtils.UriToString(this.parseResult.ContextUri), expectedPayloadKind.ToString()));
            }

            // NOTE: we interpret an empty select query option to mean that nothing should be projected
            //       (whereas a missing select query option means everything should be projected).
            string selectQueryOption = this.parseResult.SelectQueryOption;

            if (selectQueryOption != null)
            {
                if (detectedPayloadKind != ODataPayloadKind.ResourceSet && detectedPayloadKind != ODataPayloadKind.Resource && detectedPayloadKind != ODataPayloadKind.Delta)
                {
                    throw new ODataException(ODataErrorStrings.ODataJsonLightContextUriParser_InvalidPayloadKindWithSelectQueryOption(expectedPayloadKind.ToString()));
                }
            }
        }