Exemple #1
0
        public void AddObjectTestAction(ODataFormat format, MergeOption mergeOption, SaveChangesOptions saveChangesOption)
        {
            DataServiceContextWrapper <DefaultContainer> contextWrapper = this.CreateContext();

            contextWrapper.Context.MergeOption = mergeOption;
            if (format == ODataFormat.Json)
            {
                contextWrapper.Format.UseJson();
            }

            contextWrapper.Configurations.RequestPipeline
            .OnEntryStarting(PipelineEventsTestsHelper.ModifyPropertyValueCustomerEntity_Writing)
            .OnEntryEnding(PipelineEventsTestsHelper.ModifyPropertyValueCustomerEntry_Writing);

            Customer customer = PipelineEventsTestsHelper.CreateNewCustomer(100);

            contextWrapper.AddObject("Customer", customer);
            contextWrapper.SaveChanges(saveChangesOption);

            if (format == ODataFormat.Atom)
            {
                // Make the ATOM payload order consistence with JSON.
                Assert.IsTrue(customer.Name.EndsWith("UpdatedODataEntryPropertyValueModifyPropertyValueCustomerEntry_Writing"), "Unexpected primitive property");
            }
            else
            {
                Assert.IsTrue(customer.Name.EndsWith("UpdatedODataEntryPropertyValue"), "Unexpected primitive property");
            }

            Assert.IsTrue(customer.Auditing.ModifiedBy.Equals("UpdatedODataEntryPropertyValue"), "Unexpected complex property");
            Assert.IsTrue(customer.PrimaryContactInfo.EmailBag.Contains("UpdatedODataEntryPropertyValue"));

            contextWrapper.DeleteObject(customer);
            contextWrapper.SaveChanges();
        }
        protected override void VisitRequestOperation(IHttpRequest operation)
        {
            var requestOperation = operation as ODataRequest;

            ExceptionUtilities.CheckObjectNotNull(requestOperation, "Operation must be request");
            ODataPayloadElement rootElement = null;
            string contentType = null;

            if (requestOperation.Body != null && requestOperation.Body.RootElement != null)
            {
                rootElement = requestOperation.Body.RootElement;
                contentType = requestOperation.GetHeaderValueIfExists(Microsoft.OData.Core.ODataConstants.ContentTypeHeader);
            }

            if (rootElement != null)
            {
                ODataFormat format = null;
                if (contentType.Contains(MimeTypes.ApplicationAtomXml))
                {
                    format = ODataFormat.Atom;
                }
                else if (contentType.Contains(MimeTypes.ApplicationJson))
                {
                    format = ODataFormat.Json;
                }

                new ExpectedPayloadFixups().Fixup(rootElement, format);
            }
        }
 /// <summary>
 /// Creates a new instance of MaterializerEntry using the given entity descriptor for LoadProperty.
 /// </summary>
 /// <param name="entityDescriptor">Entity descriptor.</param>
 /// <param name="format">OData Format.</param>
 /// <param name="isTracking">Whether this entity is being tracked.</param>
 /// <remarks>Use this constructor only for LoadProperty scenario.</remarks>
 private MaterializerEntry(EntityDescriptor entityDescriptor, ODataFormat format, bool isTracking)
 {
     this.entityDescriptor = entityDescriptor;
     this.Format           = format;
     this.isTracking       = isTracking;
     this.SetFlagValue(EntryFlags.ShouldUpdateFromPayload | EntryFlags.EntityHasBeenResolved | EntryFlags.ForLoadProperty, true);
 }
Exemple #4
0
        public static string Generate(PayloadBuilder payloadBuilder, string format)
        {
            ODataFormat oDataFormat = null;

            if (format.StartsWith(UnitTestsUtil.JsonLightMimeType))
            {
                oDataFormat = ODataFormat.Json;
            }
            //else if (format.StartsWith(UnitTestsUtil.AtomFormat) ||
            //         format.StartsWith(UnitTestsUtil.MimeApplicationXml))
            //{
            //    oDataFormat = ODataFormat.Atom;
            //}
            //[Lianw] Remove Atom
            else if (format.StartsWith(UnitTestsUtil.MimeApplicationXml))
            {
                oDataFormat = ODataFormat.Metadata;
            }
            else
            {
                Assert.Fail(String.Format("Invalid format specified - {0}", format));
            }

            return(Generate(payloadBuilder, oDataFormat));
        }
 private ODataAtomOutputContext(ODataFormat format, Stream messageStream, Encoding encoding, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver) : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
 {
     try
     {
         Stream asynchronousOutputStream;
         this.messageOutputStream = messageStream;
         if (synchronous)
         {
             asynchronousOutputStream = messageStream;
         }
         else
         {
             this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
             asynchronousOutputStream      = this.asynchronousOutputStream;
         }
         this.xmlRootWriter = ODataAtomWriterUtils.CreateXmlWriter(asynchronousOutputStream, messageWriterSettings, encoding);
         this.xmlWriter     = this.xmlRootWriter;
     }
     catch (Exception exception)
     {
         if (ExceptionUtils.IsCatchableExceptionType(exception) && (messageStream != null))
         {
             messageStream.Dispose();
         }
         throw;
     }
 }
Exemple #6
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="innerExpectedResult">The inner <see cref="ReaderTestExpectedResult"/> that is doing most of the work.</param>
 /// <param name="expectedFormat">The expected <see cref="ODataFormat"/> for the specified content type.</param>
 /// <param name="settings">Settings to use.</param>
 public ContentTypeReaderTestExpectedResult(ReaderTestExpectedResult innerExpectedResult, ODataFormat expectedFormat, ReaderTestExpectedResult.ReaderTestExpectedResultSettings settings)
     : base(settings)
 {
     this.innerExpectedResult = innerExpectedResult;
     this.expectedFormat      = expectedFormat;
     this.settings            = settings;
 }
        /// <summary>
        /// Creates an <see cref="ODataCollectionWriter"/> for the specified message and its stream.
        /// </summary>
        /// <param name="format">The serialization format to create the writer for.</param>
        /// <param name="encoding">The encoding to create the writer with.</param>
        /// <param name="stream">The response stream to write to.</param>
        /// <param name="settings">Writer settings to use.</param>
        /// <param name="metadataProvider">The metadata provider to use.</param>
        /// <param name="synchronous">True if the writer is created for synchronous operation; false for asynchronous.</param>
        /// <returns>The newly created <see cref="ODataCollectionWriter"/> instance.</returns>
        /// <remarks>This is used to create the collection writer once we've obtained the stream from the response.</remarks>
        private static ODataCollectionWriter CreateCollectionWriter(
            ODataFormat format,
            Encoding encoding,
            Stream stream,
            ODataWriterSettings settings,
            DataServiceMetadataProviderWrapper metadataProvider,
            bool synchronous)
        {
            if (settings.BaseUri != null && !settings.BaseUri.IsAbsoluteUri)
            {
                throw new ODataException(Strings.ODataWriter_BaseUriMustBeNullOrAbsolute(UriUtils.UriToString(settings.BaseUri)));
            }

            switch (format)
            {
            case ODataFormat.Json:
                return(new ODataJsonCollectionWriter(stream, settings, encoding, metadataProvider, synchronous));

            case ODataFormat.Atom:
                return(new ODataAtomCollectionWriter(stream, settings, encoding, metadataProvider, synchronous));

            case ODataFormat.Default:
                Debug.Assert(false, "Should never get here as content-type negotiation should not return Default format for collection.");
                throw new ODataException(Strings.ODataCollectionWriter_CannotCreateCollectionWriterForFormat(format.ToString()));

            default:
                throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataCollectionWriter_CreateCollectionWriter_UnreachableCodePath));
            }
        }
        /// <inheritdoc/>
        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            if (headers == null)
            {
                throw Error.ArgumentNull("headers");
            }

            // call base to validate parameters and set Content-Type header based on mediaType parameter.
            base.SetDefaultContentHeaders(type, headers, mediaType);

            ODataFormat format = GetODataFormat(headers);
            IEnumerable <KeyValuePair <string, string> > oDataHeaders = GetResponseMessageHeaders(type, format, _defaultODataVersion);

            foreach (KeyValuePair <string, string> pair in oDataHeaders)
            {
                // Special case Content-Type header so that we don't end up with two values for it
                // since base.SetDefaultContentHeaders could also have set it.
                if (String.Equals("Content-Type", pair.Key, StringComparison.OrdinalIgnoreCase))
                {
                    headers.ContentType = MediaTypeHeaderValue.Parse(pair.Value);
                }
                else
                {
                    headers.TryAddWithoutValidation(pair.Key, pair.Value);
                }
            }
        }
Exemple #9
0
        public void UpdateObjectTestAction(ODataFormat format, MergeOption mergeOption, SaveChangesOptions saveChangesOption)
        {
            DataServiceContextWrapper <DefaultContainer> contextWrapper = this.CreateContext();

            contextWrapper.Context.MergeOption = mergeOption;
            contextWrapper.Context.AddAndUpdateResponsePreference = DataServiceResponsePreference.IncludeContent;
            if (format == ODataFormat.Json)
            {
                contextWrapper.Format.UseJson();
            }

            Customer customer = PipelineEventsTestsHelper.CreateNewCustomer(200);

            contextWrapper.AddObject("Customer", customer);
            contextWrapper.SaveChanges();

            contextWrapper.Configurations.RequestPipeline
            .OnEntryStarting(PipelineEventsTestsHelper.ModifyPropertyValueCustomerEntity_Writing)
            .OnEntryEnding(PipelineEventsTestsHelper.ModifyPropertyValueCustomerEntry_Writing);

            customer.Name = "update";
            contextWrapper.UpdateObject(customer);
            contextWrapper.SaveChanges(saveChangesOption);

            Assert.IsTrue(customer.Name.EndsWith("UpdatedODataEntryPropertyValue"), "Unexpected primitive property");
            Assert.IsTrue(customer.Auditing.ModifiedBy.Equals("UpdatedODataEntryPropertyValue"), "Unexpected complex property");
            Assert.IsTrue(customer.PrimaryContactInfo.EmailBag.Contains("UpdatedODataEntryPropertyValue"));

            contextWrapper.DeleteObject(customer);
            contextWrapper.SaveChanges();
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="format">The format used for the test.</param>
 /// <param name="messageWriterSettings">The message writer settings used for the test.</param>
 /// <param name="IsRequest">True if the test is writing a request. Otherwise false if it's writing a response.</param>
 /// <param name="synchronous">True if the test should be ran using synchronous API. Otherwise false if it should be ran using asynchronous APIs.</param>
 public WriterTestConfiguration(ODataFormat format, ODataMessageWriterSettings messageWriterSettings, bool IsRequest, bool synchronous)
     : base(format, messageWriterSettings.Version.Value, IsRequest, TestODataBehaviorKind.Default)
 {
     Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");
     this.Synchronous           = synchronous;
     this.MessageWriterSettings = messageWriterSettings;
 }
        /// <summary>
        /// Creates a new instance of the <see cref="PayloadMetadataParameterInterpreter"/> class.
        /// </summary>
        /// <param name="format">The response format.</param>
        /// <returns>A new instance of the <see cref="PayloadMetadataParameterInterpreter"/> class.</returns>
        internal static PayloadMetadataParameterInterpreter Create(ODataFormatWithParameters format)
        {
            ODataFormat odataFormat       = format == null ? null : format.Format;
            string      rawParameterValue = format == null ? null : format.GetParameterValue(MediaTypeParameterName);

            return(new PayloadMetadataParameterInterpreter(odataFormat, rawParameterValue));
        }
            public void AddBaseUriStringToExpectedDescriptors(string baseUri, ODataFormat format)
            {
                if (this.GetExpectedDescriptors(format) != null)
                {
                    foreach (var expectedDescriptorsForFormat in this.GetExpectedDescriptors(format))
                    {
                        foreach (MyOperationDescriptor od in expectedDescriptorsForFormat)
                        {
                            if (format == ODataFormat.Json && od.Metadata[0] == '#')
                            {
                                od.Metadata = baseUri + "/$metadata" + od.Metadata;
                            }
                            else if (this.AddBaseUriToMetadata == null || this.AddBaseUriToMetadata.Value)
                            {
                                od.Metadata = baseUri + "/" + od.Metadata;
                            }

                            if (this.AddBaseUriToTarget == null || this.AddBaseUriToTarget.Value)
                            {
                                od.Target = baseUri + "/" + od.Target;
                            }
                        }
                    }
                }
            }
        /// <summary>
        /// Visits the root element of the operation.
        /// </summary>
        /// <param name="operation">The operation to visit</param>
        protected override void VisitResponseOperation(HttpResponseData operation)
        {
            var responseOperation = operation as ODataResponse;

            ExceptionUtilities.CheckObjectNotNull(responseOperation, "Operation must be a response");
            ODataPayloadElement rootElement = null;
            string contentType = null;

            if (responseOperation.RootElement != null)
            {
                rootElement = responseOperation.RootElement;
                contentType = responseOperation.GetHeaderValueIfExists(Microsoft.OData.ODataConstants.ContentTypeHeader);
            }

            if (rootElement != null)
            {
                ODataFormat format = null;
                if (contentType.Contains(MimeTypes.ApplicationJson))
                {
                    format = ODataFormat.Json;
                }

                new ExpectedPayloadFixups().Fixup(rootElement, format);
            }
        }
Exemple #14
0
        public void TestCustomMediaTypeGetFormatFromContentType()
        {
            var resolver = new MyMediaTypeResolver();

            foreach (var payloadKind in Enum.GetValues(typeof(ODataPayloadKind)).Cast <ODataPayloadKind>())
            {
                if (payloadKind == ODataPayloadKind.Unsupported)
                {
                    continue;
                }

                string         contentType       = "text/x-A";
                string         expectedBoundary  = null;
                ODataMediaType expectedMediaType = MyFormat.MediaTypeWithFormatA.MediaType;
                if (payloadKind == ODataPayloadKind.Batch)
                {
                    expectedBoundary  = "ba_" + Guid.NewGuid();
                    contentType      += ";boundary=" + expectedBoundary;
                    expectedMediaType = new ODataMediaType("text", "x-A", new KeyValuePair <string, string>("boundary", expectedBoundary));
                }

                ODataMediaType   mediaType;
                Encoding         encoding;
                ODataPayloadKind selectedPayloadKind;
                string           batchBoundary;
                ODataFormat      actual = MediaTypeUtils.GetFormatFromContentType(contentType, new[] { payloadKind }, resolver, out mediaType, out encoding, out selectedPayloadKind, out batchBoundary);

                Console.WriteLine(payloadKind);
                actual.ShouldBeEquivalentTo(MyFormat.Instance);
                mediaType.ShouldBeEquivalentTo(expectedMediaType);
                encoding.ShouldBeEquivalentTo(payloadKind == ODataPayloadKind.BinaryValue ? null : Encoding.UTF8);
                selectedPayloadKind.ShouldBeEquivalentTo(payloadKind);
                batchBoundary.ShouldBeEquivalentTo(expectedBoundary);
            }
        }
        public void TestCustomMediaTypeGetFormatFromContentType()
        {
            var resolver = new MyMediaTypeResolver();

            foreach (var payloadKind in Enum.GetValues(typeof(ODataPayloadKind)).Cast <ODataPayloadKind>())
            {
                if (payloadKind == ODataPayloadKind.Unsupported)
                {
                    continue;
                }

                string         contentType       = "text/x-A";
                string         expectedBoundary  = null;
                ODataMediaType expectedMediaType = MyFormat.MediaTypeWithFormatA.MediaType;
                if (payloadKind == ODataPayloadKind.Batch)
                {
                    expectedBoundary  = "ba_" + Guid.NewGuid();
                    contentType      += ";boundary=" + expectedBoundary;
                    expectedMediaType = new ODataMediaType("text", "x-A", new KeyValuePair <string, string>("boundary", expectedBoundary));
                }

                ODataMediaType   mediaType;
                Encoding         encoding;
                ODataPayloadKind selectedPayloadKind;
                ODataFormat      actual = MediaTypeUtils.GetFormatFromContentType(contentType, new[] { payloadKind }, resolver, out mediaType, out encoding, out selectedPayloadKind);

                Assert.Equal(MyFormat.Instance, actual);
                Assert.Equal(expectedMediaType.FullTypeName, mediaType.FullTypeName);
                Assert.Equal(payloadKind == ODataPayloadKind.BinaryValue ? null : Encoding.UTF8, encoding);
                Assert.Equal(payloadKind, selectedPayloadKind);
            }
        }
Exemple #16
0
        /// <summary>Constructor.</summary>
        /// <param name="format">The format for this input context.</param>
        /// <param name="reader">The reader to use.</param>
        /// <param name="contentType">The content type of the message to read.</param>
        /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param>
        /// <param name="version">The OData protocol version to be used for reading the payload.</param>
        /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
        /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param>
        /// <param name="payloadKindDetectionState">JSON Ligth specific state stored during payload kind detection (or null if no payload kind detection happened).</param>
        internal ODataJsonLightInputContext(
            ODataFormat format,
            TextReader reader,
            MediaType contentType,
            ODataMessageReaderSettings messageReaderSettings,
            ODataVersion version,
            bool readingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver,
            ODataJsonLightPayloadKindDetectionState payloadKindDetectionState)
            : base(format, messageReaderSettings, version, readingResponse, synchronous, model, urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(reader != null, "reader != null");
            Debug.Assert(contentType != null, "contentType != null");

            try
            {
                ExceptionUtils.CheckArgumentNotNull(format, "format");
                ExceptionUtils.CheckArgumentNotNull(messageReaderSettings, "messageReaderSettings");
            }
            catch (ArgumentNullException)
            {
                // Dispose the message stream if we failed to create the input context.
                reader.Dispose();
                throw;
            }

            try
            {
                this.textReader = reader;

                if (contentType.HasStreamingSetToTrue())
                {
                    this.jsonReader = new BufferingJsonReader(
                        this.textReader,
                        ODataAnnotationNames.ODataError,
                        messageReaderSettings.MessageQuotas.MaxNestingDepth,
                        ODataFormat.Json);
                }
                else
                {
                    // If we have a non-streaming Json Light content type we need to use the re-ordering Json reader
                    this.jsonReader = new ReorderingJsonReader(this.textReader, messageReaderSettings.MessageQuotas.MaxNestingDepth);
                }
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && reader != null)
                {
                    reader.Dispose();
                }

                throw;
            }

            this.payloadKindDetectionState = payloadKindDetectionState;
        }
Exemple #17
0
        /// <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);
            }
        }
        /// <summary>
        /// Asynchronously create ATOM output context.
        /// </summary>
        /// <param name="format">The format to create the output context for.</param>
        /// <param name="message">The message to use.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        /// <returns>Task which when completed returns the newly created output context.</returns>
        internal static Task <ODataOutputContext> CreateAsync(
            ODataFormat format,
            ODataMessage message,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(format == ODataFormat.Atom, "This method only supports the ATOM format.");
            Debug.Assert(message != null, "message != null");
            Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");

            return(message.GetStreamAsync()
                   .FollowOnSuccessWith(
                       (streamTask) => (ODataOutputContext) new ODataAtomOutputContext(
                           format,
                           streamTask.Result,
                           encoding,
                           messageWriterSettings,
                           writingResponse,
                           false,
                           model,
                           urlResolver)));
        }
        private static string GetLiteralValue(object value, ODataFormat format, PayloadGeneratorSettings settings)
        {
            JsonPayloadGenerator generator;

            if (format == ODataFormat.Json)
            {
                generator = new JsonLightPayloadGenerator(settings);
            }
            else
            {
                Assert.Fail("Format not supported by UriOperationParameterGenerator.");
                return(null);
            }

            var payloadBuilder = value as PayloadBuilder;

            if (payloadBuilder != null)
            {
                return(generator.GenerateLiteral(payloadBuilder));
            }

            var collectionBuilder = value as CollectionPropertyPayloadBuilder;

            if (collectionBuilder != null)
            {
                return(generator.GenerateLiteral(collectionBuilder));
            }

            // Use the key syntax since that will give us single quotes and other formatting that is not used for literals as property values
            return(JsonPrimitiveTypesUtil.PrimitiveToKeyString(value, value.GetType()));
        }
        /// <summary>
        /// Create ATOM output context.
        /// </summary>
        /// <param name="format">The format to create the output context for.</param>
        /// <param name="message">The message to use.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        /// <returns>The newly created output context.</returns>
        internal static ODataOutputContext Create(
            ODataFormat format,
            ODataMessage message,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(format == ODataFormat.Atom, "This method only supports the ATOM format.");
            Debug.Assert(message != null, "message != null");
            Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");

            Stream messageStream = message.GetStream();

            return(new ODataAtomOutputContext(
                       format,
                       messageStream,
                       encoding,
                       messageWriterSettings,
                       writingResponse,
                       true,
                       model,
                       urlResolver));
        }
        /// <summary>
        /// Asynchronously create JSON input context.
        /// </summary>
        /// <param name="format">The format for the input context.</param>
        /// <param name="message">The message to use.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param>
        /// <param name="version">The OData protocol version to be used for reading the payload.</param>
        /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param>
        /// <returns>Task which when completed returns the newly created input context.</returns>
        internal static Task <ODataInputContext> CreateAsync(
            ODataFormat format,
            ODataMessage message,
            Encoding encoding,
            ODataMessageReaderSettings messageReaderSettings,
            ODataVersion version,
            bool readingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(message != null, "message != null");
            Debug.Assert(messageReaderSettings != null, "messageReaderSettings != null");

            return(message.GetStreamAsync()
                   .FollowOnSuccessWith(
                       (streamTask) => (ODataInputContext) new ODataJsonInputContext(
                           format,
                           streamTask.Result,
                           encoding,
                           messageReaderSettings,
                           version,
                           readingResponse,
                           false,
                           model,
                           urlResolver)));
        }
        /// <summary>Constructor.</summary>
        /// <param name="format">The format for this input context.</param>
        /// <param name="reader">The reader to read data from.</param>
        /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param>
        /// <param name="version">The OData protocol version to be used for reading the payload.</param>
        /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
        /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param>
        internal ODataJsonInputContext(
            ODataFormat format,
            TextReader reader,
            ODataMessageReaderSettings messageReaderSettings,
            ODataVersion version,
            bool readingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageReaderSettings, version, readingResponse, synchronous, model, urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(reader != null, "reader != null");

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

            try
            {
                this.textReader = reader;
                this.jsonReader = new BufferingJsonReader(this.textReader, /*removeDuplicateProperties*/ this.UseServerFormatBehavior, messageReaderSettings.MessageQuotas.MaxNestingDepth);
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && reader != null)
                {
                    reader.Dispose();
                }

                throw;
            }
        }
        /// <summary>
        /// Create JSON input context.
        /// </summary>
        /// <param name="format">The format for the input context.</param>
        /// <param name="message">The message to use.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param>
        /// <param name="version">The OData protocol version to be used for reading the payload.</param>
        /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param>
        /// <returns>The newly created input context.</returns>
        internal static ODataInputContext Create(
            ODataFormat format,
            ODataMessage message,
            Encoding encoding,
            ODataMessageReaderSettings messageReaderSettings,
            ODataVersion version,
            bool readingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(message != null, "message != null");
            Debug.Assert(messageReaderSettings != null, "messageReaderSettings != null");

            Stream messageStream = message.GetStream();

            return(new ODataJsonInputContext(
                       format,
                       messageStream,
                       encoding,
                       messageReaderSettings,
                       version,
                       readingResponse,
                       true,
                       model,
                       urlResolver));
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="format">The format used for the test.</param>
 /// <param name="version">The OData protocol version to be used for the payload.</param>
 /// <param name="request">True if the test is reading a request. Otherwise false if it's reading a response.</param>
 public TestConfiguration(ODataFormat format, ODataVersion version, bool request, TestODataBehaviorKind behaviorKind)
 {
     this.Format          = format;
     this.Version         = version;
     this.IsRequest       = request;
     this.RunBehaviorKind = behaviorKind;
 }
 private ODataJsonOutputContext(ODataFormat format, Stream messageStream, Encoding encoding, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver) : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
 {
     try
     {
         Stream asynchronousOutputStream;
         this.messageOutputStream = messageStream;
         if (synchronous)
         {
             asynchronousOutputStream = messageStream;
         }
         else
         {
             this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
             asynchronousOutputStream      = this.asynchronousOutputStream;
         }
         this.textWriter = new StreamWriter(asynchronousOutputStream, encoding);
         this.jsonWriter = new Microsoft.Data.OData.Json.JsonWriter(this.textWriter, messageWriterSettings.Indent);
     }
     catch (Exception exception)
     {
         if (ExceptionUtils.IsCatchableExceptionType(exception) && (messageStream != null))
         {
             messageStream.Dispose();
         }
         throw;
     }
 }
        private void WriteAnnotationAtStartExpandedFeedShouldFail(ODataFormat format)
        {
            Action <ODataWriter> action = (odataWriter) =>
            {
                var entryToWrite = new ODataResource {
                    Properties = new[] { new ODataProperty {
                                             Name = "ID", Value = 1
                                         } }
                };
                odataWriter.WriteStart(entryToWrite);

                ODataNestedResourceInfo navLink = new ODataNestedResourceInfo {
                    Name = "ResourceSetNavigationProperty", IsCollection = true
                };

                odataWriter.WriteStart(navLink);

                var feedToWrite = new ODataResourceSet {
                    Id = new Uri("urn:feedId")
                };
                feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("custom.StartFeedAnnotation", PrimitiveValue1));

                odataWriter.WriteStart(feedToWrite);
            };

            Action testResponse = () => this.WriteAnnotationsAndValidatePayload(action, EntitySet, format, null, request: false, createFeedWriter: false);

            testResponse.ShouldThrow <ODataException>().WithMessage(Strings.ODataJsonLightWriter_InstanceAnnotationNotSupportedOnExpandedResourceSet);

            Action testRequest = () => this.WriteAnnotationsAndValidatePayload(action, EntitySet, format, null, request: true, createFeedWriter: false);

            testRequest.ShouldThrow <ODataException>().WithMessage(Strings.ODataJsonLightWriter_InstanceAnnotationNotSupportedOnExpandedResourceSet);
        }
        public void ContentTypeHeaderParsingErrorTest()
        {
            var testCases = new ContentTypeTestCase[]
            {
                new ContentTypeTestCase
                {
                    ContentType       = null,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_NoneOrEmptyContentTypeHeader")
                },
                new ContentTypeTestCase
                {
                    ContentType       = string.Empty,
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_NoneOrEmptyContentTypeHeader")
                },
                new ContentTypeTestCase
                {
                    ContentType       = ";foo=bar",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("HttpUtils_MediaTypeRequiresSlash", ";foo=bar")
                },
                new ContentTypeTestCase
                {
                    ContentType       = "application/*",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_WildcardInContentType", "application/*")
                },
                new ContentTypeTestCase
                {
                    ContentType       = "*/*",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("ODataMessageReader_WildcardInContentType", "*/*")
                },
                new ContentTypeTestCase
                {
                    ContentType       = "application/json, application/xml",
                    ExpectedException = ODataExpectedExceptions.ODataContentTypeException("MediaTypeUtils_NoOrMoreThanOneContentTypeSpecified", "application/json, application/xml")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                this.ReaderTestConfigurationProvider.AllFormatConfigurations.Where(tc => tc.Format != ODataFormat.Json),
                (testCase, testConfiguration) =>
            {
                // create a message reader and call GetFormat; this should fail with the expected error message
                TestMessage testMessage = TestReaderUtils.CreateInputMessageFromStream(new TestStream(), testConfiguration);
                testMessage.SetHeader(Microsoft.OData.Core.ODataConstants.ContentTypeHeader, testCase.ContentType);
                testMessage.SetHeader(Microsoft.OData.Core.ODataConstants.ContentLengthHeader, testCase.ContentLength.ToString());

                TestExceptionUtils.ExpectedException(
                    this.Assert,
                    () =>
                {
                    using (ODataMessageReaderTestWrapper messageReader = TestReaderUtils.CreateMessageReader(testMessage, null, testConfiguration))
                    {
                        ODataFormat actualFormat = messageReader.DetectPayloadKind().Single().Format;
                    }
                },
                    testCase.ExpectedException,
                    this.ExceptionVerifier);
            });
        }
        /// <summary>
        /// Sets the acceptable media types and character sets from which the content type will be computed when writing the payload.
        /// </summary>
        /// <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>
        /// <remarks>Calling this method replaces any previously set content-type settings.</remarks>
        public void SetContentType(string acceptableMediaTypes, string acceptableCharSets)
        {
            ExceptionUtils.CheckArgumentNotNull(acceptableMediaTypes, "acceptableMediaTypes");

            this.acceptMediaTypes = acceptableMediaTypes;
            this.acceptCharSets   = acceptableCharSets;
            this.format           = ODataFormat.Default;
        }
Exemple #29
0
 /// <summary>
 /// Creates a new instance of Json writer.
 /// </summary>
 /// <param name="writer">Writer to which text needs to be written.</param>
 /// <param name="indent">If the output should be indented or not.</param>
 /// <param name="jsonFormat">The json-based format to use when writing.</param>
 internal JsonWriter(TextWriter writer, bool indent, ODataFormat jsonFormat)
 {
     DebugUtils.CheckNoExternalCallers();
     Debug.Assert(jsonFormat == ODataFormat.Json || jsonFormat == ODataFormat.VerboseJson, "Expected a json-based format.");
     this.writer = new IndentedTextWriter(writer, indent);
     this.scopes = new Stack <Scope>();
     this.mustWriteDecimalPointInDoubleValues = jsonFormat == ODataFormat.Json;
 }
Exemple #30
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format used for the test.</param>
        /// <param name="messageReaderSettings">The message reader settings used for the test.</param>
        /// <param name="readerRequest">True if the test is reading a request. Otherwise false if it's reading a response.</param>
        /// <param name="synchronous">True if the test should be ran using synchronous API. Otherwise false if it should be ran using asynchronous APIs.</param>
        /// <param name="version">The OData protocol version to be used for reading the payload.</param>
        public ReaderTestConfiguration(ODataFormat format, ODataMessageReaderSettings messageReaderSettings, bool IsRequest, bool synchronous, ODataVersion version = ODataVersion.V4)
            : base(format, version, IsRequest, TestODataBehaviorKind.Default)
        {
            Debug.Assert(messageReaderSettings != null, "readerSettings != null");

            this.MessageReaderSettings = messageReaderSettings;
            this.Synchronous           = synchronous;
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="format">The format for this output context.</param>
 /// <param name="messageStream">The message stream to write the payload to.</param>
 /// <param name="mediaType">The specific media type being written.</param>
 /// <param name="encoding">The encoding to use for the payload.</param>
 /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
 /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
 /// <param name="synchronous">true if the output should be written synchronously; false if it should be written asynchronously.</param>
 /// <param name="model">The model to use.</param>
 /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
 internal ODataJsonLightOutputContext(ODataFormat format, Stream messageStream, ODataMediaType mediaType, Encoding encoding, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver)
     : base(format, messageStream, encoding, messageWriterSettings, writingResponse, synchronous, mediaType.HasIeee754CompatibleSetToTrue(), model, urlResolver)
 {
     Debug.Assert(messageStream != null, "messageStream != null");
     Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");
     Debug.Assert(mediaType != null, "mediaType != null");
     Uri metadataDocumentUri = messageWriterSettings.MetadataDocumentUri;
     this.metadataLevel = JsonLightMetadataLevel.Create(mediaType, metadataDocumentUri, model, writingResponse);
 }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="reader">The text reader to read input characters from.</param>
        /// <param name="inStreamErrorPropertyName">The name of the property that denotes an in-stream error.</param>
        /// <param name="maxInnerErrorDepth">The maximum number of recursive internalexception objects to allow when reading in-stream errors.</param>
        /// <param name="jsonFormat">The specific JSON-based format expected by the reader.</param>
        /// <param name="isIeee754Compatible">If it is IEEE754 Compatible</param>
        internal BufferingJsonReader(TextReader reader, string inStreamErrorPropertyName, int maxInnerErrorDepth, ODataFormat jsonFormat, bool isIeee754Compatible)
            : base(reader, jsonFormat, isIeee754Compatible)
        {
            Debug.Assert(reader != null, "reader != null");

            this.inStreamErrorPropertyName = inStreamErrorPropertyName;
            this.maxInnerErrorDepth = maxInnerErrorDepth;
            this.bufferedNodesHead = null;
            this.currentBufferedNode = null;
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="format">The format for this output context.</param>
 /// <param name="jsonWriter">The JSON writer to write to.</param>
 /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
 /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
 /// <param name="synchronous">true if the output should be written synchronously; false if it should be written asynchronously.</param>
 /// <param name="model">The model to use.</param>
 /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
 private ODataJsonOutputContext(
     ODataFormat format,
     JsonWriter jsonWriter,
     ODataMessageWriterSettings messageWriterSettings,
     bool writingResponse,
     bool synchronous,
     IEdmModel model,
     IODataUrlResolver urlResolver)
     : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
 {
     this.jsonWriter = jsonWriter;
 }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="textWriter">The text writer to write to.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="model">The model to use.</param>
        protected internal ODataJsonOutputContextBase(
            ODataFormat format,
            TextWriter textWriter,
            ODataMessageWriterSettings messageWriterSettings,
            IEdmModel model)
            : base(format, messageWriterSettings, false /*writingResponse*/, true /*synchronous*/, model, null /*urlResolver*/)
        {
            Debug.Assert(textWriter != null, "textWriter != null");

            this.textWriter = textWriter;
            this.jsonWriter = new JsonWriter(this.textWriter, messageWriterSettings.Indent, format, true /*isIeee754Compatible*/);
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="textWriter">The text writer to write to.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="model">The model to use.</param>
        internal ODataJsonLightOutputContext(
            ODataFormat format,
            TextWriter textWriter,
            ODataMessageWriterSettings messageWriterSettings,
            IEdmModel model)
            : base(format, textWriter, messageWriterSettings, model)
        {
            Debug.Assert(!this.WritingResponse, "Expecting WritingResponse to always be false for this constructor, so no need to validate the MetadataDocumentUri on the writer settings.");
            Debug.Assert(textWriter != null, "textWriter != null");
            Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");

            this.metadataLevel = new JsonMinimalMetadataLevel();
        }
 /// <summary>Constructor.</summary>
 /// <param name="format">The format for this input context.</param>
 /// <param name="messageStream">The stream to read data from.</param>
 /// <param name="contentType">The content type of the message to read.</param>
 /// <param name="encoding">The encoding to use to read the input.</param>
 /// <param name="messageReaderSettings">Configuration settings of the OData reader.</param>
 /// <param name="readingResponse">true if reading a response message; otherwise false.</param>
 /// <param name="synchronous">true if the input should be read synchronously; false if it should be read asynchronously.</param>
 /// <param name="model">The model to use.</param>
 /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs read from the payload.</param>
 internal ODataJsonLightInputContext(
     ODataFormat format,
     Stream messageStream,
     ODataMediaType contentType,
     Encoding encoding,
     ODataMessageReaderSettings messageReaderSettings,
     bool readingResponse,
     bool synchronous,
     IEdmModel model,
     IODataUrlResolver urlResolver)
     : this(format, CreateTextReaderForMessageStreamConstructor(messageStream, encoding), contentType, messageReaderSettings, readingResponse, synchronous, model, urlResolver)
 {
 }
Exemple #37
0
        /// <summary>
        /// Creates a new instance of Json writer.
        /// </summary>
        /// <param name="writer">Writer to which text needs to be written.</param>
        /// <param name="indent">If the output should be indented or not.</param>
        /// <param name="jsonFormat">The json-based format to use when writing.</param>
        /// <param name="isIeee754Compatible">if it is IEEE754Compatible</param>
        internal JsonWriter(TextWriter writer, bool indent, ODataFormat jsonFormat, bool isIeee754Compatible)
        {
            Debug.Assert(jsonFormat == ODataFormat.Json, "Expected a json-based format.");

            if (indent == true)
            {
                this.writer = new IndentedTextWriter(writer);
            }
            else
            {
                this.writer = new NonIndentedTextWriter(writer);
            }

            this.scopes = new Stack<Scope>();
            this.isIeee754Compatible = isIeee754Compatible;
        }
        protected internal ODataJsonOutputContextBase(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            bool isIeee754Compatible,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
        {
            Debug.Assert(messageStream != null, "messageStream != null");

            try
            {
                this.messageOutputStream = messageStream;

                Stream outputStream;
                if (synchronous)
                {
                    outputStream = messageStream;
                }
                else
                {
                    this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
                    outputStream = this.asynchronousOutputStream;
                }

                this.textWriter = new StreamWriter(outputStream, encoding);
                
                // COMPAT 2: JSON indentation - WCFDS indents only partially, it inserts newlines but doesn't actually insert spaces for indentation
                // in here we allow the user to specify if true indentation should be used or if the limited functionality is enough.
                this.jsonWriter = new JsonWriter(this.textWriter, messageWriterSettings.Indent, format, isIeee754Compatible);
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="messageStream">The message stream to write the payload to.</param>
        /// <param name="encoding">The encoding to use for the payload.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="synchronous">true if the output should be written synchronously; false if it should be written asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        private ODataAtomOutputContext(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
        {
            Debug.Assert(messageStream != null, "stream != null");

            try
            {
                this.messageOutputStream = messageStream;

                Stream outputStream;
                if (synchronous)
                {
                    outputStream = messageStream;
                }
                else
                {
                    this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
                    outputStream = this.asynchronousOutputStream;
                }

                this.xmlRootWriter = ODataAtomWriterUtils.CreateXmlWriter(outputStream, messageWriterSettings, encoding);
                this.xmlWriter = this.xmlRootWriter;
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="format">The format for this output context.</param>
        /// <param name="messageStream">The message stream to write the payload to.</param>
        /// <param name="encoding">The encoding to use for the payload.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="synchronous">true if the output should be written synchronously; false if it should be written asynchronously.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        private ODataJsonOutputContext(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
        {
            try
            {
                this.messageOutputStream = messageStream;

                Stream outputStream;
                if (synchronous)
                {
                    outputStream = messageStream;
                }
                else
                {
                    this.asynchronousOutputStream = new AsyncBufferedStream(messageStream);
                    outputStream = this.asynchronousOutputStream;
                }

                this.textWriter = new StreamWriter(outputStream, encoding);

                this.jsonWriter = new JsonWriter(this.textWriter, messageWriterSettings.Indent);
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
        internal ODataAtomInputContext(
            ODataFormat format,
            Stream messageStream,
            Encoding encoding,
            ODataMessageReaderSettings messageReaderSettings,
            bool readingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageReaderSettings, readingResponse, synchronous, model, urlResolver)
        {
            Debug.Assert(messageStream != null, "stream != null");

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

                // Which encoding do we use when reading XML payloads
                this.baseXmlReader = ODataAtomReaderUtils.CreateXmlReader(messageStream, encoding, messageReaderSettings);

                // For WCF DS Server behavior we need to turn off xml:base processing for V1/V2 back compat.
                this.xmlReader = new BufferingXmlReader(
                    this.baseXmlReader,
                    /*parentXmlReader*/ null,
                    messageReaderSettings.BaseUri,
                    /*disableXmlBase*/ false,
                    messageReaderSettings.MessageQuotas.MaxNestingDepth);
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && messageStream != null)
                {
                    messageStream.Dispose();
                }

                throw;
            }
        }
        protected void WriteAnnotationsAndValidatePayload(Action<ODataWriter> action, ODataFormat format, string expectedPayload, bool request, bool createFeedWriter)
        {
            var writerSettings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true, EnableAtom = true };
            writerSettings.SetContentType(format);
            writerSettings.SetServiceDocumentUri(new Uri("http://www.example.com/"));

            MemoryStream stream = new MemoryStream();
            if (request)
            {
                IODataRequestMessage requestMessageToWrite = new InMemoryMessage { Method = "GET", Stream = stream };
                using (var messageWriter = new ODataMessageWriter(requestMessageToWrite, writerSettings, Model))
                {
                    ODataWriter odataWriter = createFeedWriter ? messageWriter.CreateODataFeedWriter(EntitySet, EntityType) : messageWriter.CreateODataEntryWriter(EntitySet, EntityType);
                    action(odataWriter);
                }
            }
            else
            {
                IODataResponseMessage responseMessageToWrite = new InMemoryMessage { StatusCode = 200, Stream = stream };
                using (var messageWriter = new ODataMessageWriter(responseMessageToWrite, writerSettings, Model))
                {
                    ODataWriter odataWriter = createFeedWriter ? messageWriter.CreateODataFeedWriter(EntitySet, EntityType) : messageWriter.CreateODataEntryWriter(EntitySet, EntityType);
                    action(odataWriter);
                }
            }

            stream.Position = 0;
            string payload = (new StreamReader(stream)).ReadToEnd();
            if (format == ODataFormat.Atom)
            {
                // The <updated> element is computed dynamically, so we remove it from the both the baseline and the actual payload.
                payload = Regex.Replace(payload, "<updated>[^<]*</updated>", "");
                expectedPayload = Regex.Replace(expectedPayload, "<updated>[^<]*</updated>", "");
            }

            Assert.Equal(expectedPayload, payload);
        }
Exemple #43
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="reader">The text reader to read input characters from.</param>
        /// <param name="jsonFormat">The specific JSON-based format expected by the reader.</param>
        /// <param name="isIeee754Compatible">If it is isIeee754Compatible</param>
        public JsonReader(TextReader reader, ODataFormat jsonFormat, bool isIeee754Compatible)
        {
            Debug.Assert(reader != null, "reader != null");
            Debug.Assert(jsonFormat == ODataFormat.Json, "Expected a json-based format to create a JsonReader");

            this.nodeType = JsonNodeType.None;
            this.nodeValue = null;
            this.reader = reader;
            this.characterBuffer = new char[InitialCharacterBufferSize];
            this.storedCharacterCount = 0;
            this.tokenStartIndex = 0;
            this.endOfInputReached = false;
            this.isIeee754Compatible = isIeee754Compatible;
            this.allowAnnotations = jsonFormat == ODataFormat.Json;
            this.scopes = new Stack<Scope>();
            this.scopes.Push(new Scope(ScopeType.Root));
        }
 /// <summary>
 /// Sets the format to be used when writing the payload. This will automatically set a compatible 
 /// content type header.
 /// </summary>
 /// <param name="payloadFormat">The format to use for writing the payload.</param>
 /// <remarks>Calling this method replaces any previously set content-type settings.</remarks>
 public void SetContentType(ODataFormat payloadFormat)
 {
     this.acceptCharSets = null;
     this.acceptMediaTypes = null;
     this.format = payloadFormat;
 }
        /// <summary>
        /// Sets the acceptable media types and character sets from which the content type will be computed when writing the payload.
        /// </summary>
        /// <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>
        /// <remarks>Calling this method replaces any previously set content-type settings.</remarks>
        public void SetContentType(string acceptableMediaTypes, string acceptableCharSets)
        {
            ExceptionUtils.CheckArgumentNotNull(acceptableMediaTypes, "acceptableMediaTypes");

            this.acceptMediaTypes = acceptableMediaTypes;
            this.acceptCharSets = acceptableCharSets;
            this.format = ODataFormat.Default;
        }
        /// <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 (or writer creation) methods on the <see cref="ODataMessageWriter"/>.
        /// If it is sufficient to set the headers when the write (or writer creation) methods on the <see cref="ODataMessageWriter"/>
        /// 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 this message writer.</param>
        internal void SetHeaders(ODataPayloadKind payloadKind)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(payloadKind != ODataPayloadKind.Unsupported, "payloadKind != ODataPayloadKind.Unsupported");

            this.writerPayloadKind = payloadKind;

            // Determine the content type and format from the settings.
            MediaType mediaType;
            this.format = MediaTypeUtils.GetContentTypeFromSettings(this.settings, payloadKind, out mediaType, out this.encoding);

            string contentType;

            if (payloadKind == ODataPayloadKind.Batch)
            {
                // Note that this serves as verification only for now, since we only support a single content type and format for $batch payloads.
                Debug.Assert(this.format == ODataFormat.Default, "$batch should only support default format since it's format independent.");
                Debug.Assert(mediaType.TypeName == MimeConstants.MimeMultipartMixed, "$batch content type is currently only supported to be multipart/mixed.");

                //// TODO: Bug 135611: What about the encoding - should we verify that it's 7bit US-ASCII only?

                this.batchBoundary = ODataBatchWriterUtils.CreateBatchBoundary(this.writingResponse);

                // Set the content type header here since all headers have to be set before getting the stream
                // Note that the mediaType may have additional parameters, which we ignore here (intentional as per MIME spec).
                // Note that we always generate a new boundary string here, even if the accept header contained one.
                // We need the boundary to be as unique as possible to avoid possible collision with content of the batch operation payload.
                // Our boundary string are generated to fulfill this requirement, client specified ones might not which might lead to wrong responses
                // and at least in theory security issues.
                contentType = ODataBatchWriterUtils.CreateMultipartMixedContentType(this.batchBoundary);
            }
            else
            {
                this.batchBoundary = null;

                // compute the content type (incl. charset) and set the Content-Type header on the response message
                contentType = HttpUtils.BuildContentType(mediaType, this.encoding);
            }

            this.message.SetHeader(ODataHttpHeaders.ContentType, contentType);

            // Set the data service version
            ODataUtilsInternal.SetDataServiceVersion(this.message, this.settings);
        }
        internal ODataJsonLightInputContext(
            ODataFormat format,
            TextReader reader,
            ODataMediaType contentType,
            ODataMessageReaderSettings messageReaderSettings,
            bool readingResponse,
            bool synchronous,
            IEdmModel model,
            IODataUrlResolver urlResolver)
            : base(format, messageReaderSettings, readingResponse, synchronous, model, urlResolver)
        {
            Debug.Assert(reader != null, "reader != null");
            Debug.Assert(contentType != null, "contentType != null");

            try
            {
                ExceptionUtils.CheckArgumentNotNull(format, "format");
                ExceptionUtils.CheckArgumentNotNull(messageReaderSettings, "messageReaderSettings");
            }
            catch (ArgumentNullException)
            {
                // Dispose the message stream if we failed to create the input context.
                reader.Dispose();
                throw;
            }

            try
            {
                this.textReader = reader;

                if (contentType.HasStreamingSetToTrue())
                {
                    this.jsonReader = new BufferingJsonReader(
                        this.textReader,
                        JsonLightConstants.ODataErrorPropertyName,
                        messageReaderSettings.MessageQuotas.MaxNestingDepth,
                        ODataFormat.Json,
                        contentType.HasIeee754CompatibleSetToTrue());
                }
                else
                {
                    // If we have a non-streaming Json Light content type we need to use the re-ordering Json reader
                    this.jsonReader = new ReorderingJsonReader(this.textReader, messageReaderSettings.MessageQuotas.MaxNestingDepth, contentType.HasIeee754CompatibleSetToTrue());
                }
            }
            catch (Exception e)
            {
                // Dispose the message stream if we failed to create the input context.
                if (ExceptionUtils.IsCatchableExceptionType(e) && reader != null)
                {
                    reader.Dispose();
                }

                throw;
            }

            // dont know how to get MetadataDocumentUri uri here, messageReaderSettings do not have one
            // Uri metadataDocumentUri = messageReaderSettings..MetadataDocumentUri == null ? null : messageReaderSettings.MetadataDocumentUri.BaseUri;
            // the uri here is used here to create the FullMetadataLevel can pass null in
            this.metadataLevel = JsonLight.JsonLightMetadataLevel.Create(contentType, null, model, readingResponse);
        }
 public AndConstraint<MediaTypeAssertions> HaveExactFormat(ODataFormat format)
 {
     this.Format.Should().BeSameAs(format);
     return new AndConstraint<MediaTypeAssertions>(this);
 }
        private void WriteAnnotationOnExpandedEntriesNotInExpandedFeed(IEdmNavigationSource navigationSource, ODataFormat format, string expectedPayload)
        {
            Action<ODataWriter> action = (odataWriter) =>
            {
                var entryToWrite = new ODataEntry {Properties = new[] {new ODataProperty {Name = "ID", Value = 1}}};
                odataWriter.WriteStart(entryToWrite);

                    ODataNavigationLink navLink = new ODataNavigationLink {Name = "ResourceNavigationProperty", IsCollection = false};
                    if (format == ODataFormat.Atom)
                    {
                        navLink.Url = new Uri("http://service/navLink", UriKind.RelativeOrAbsolute);
                    }

                    odataWriter.WriteStart(navLink);

                        entryToWrite = new ODataEntry {Properties = new[] {new ODataProperty {Name = "ID", Value = 1}}};
                        entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.StartAnnotation", PrimitiveValue1));
                        odataWriter.WriteStart(entryToWrite);
                            entryToWrite.EditLink = tempUri;
                            entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.EndAnnotation", PrimitiveValue1));
                        odataWriter.WriteEnd();

                    odataWriter.WriteEnd();
                odataWriter.WriteEnd();
            };

            this.WriteAnnotationsAndValidatePayload(action, navigationSource, format, expectedPayload, request: false, createFeedWriter: false);
            this.WriteAnnotationsAndValidatePayload(action, navigationSource, format, expectedPayload, request: true, createFeedWriter: false);
        }
        private void WriteAnnotationAtEndOnTopLevelFeed(string expectedPayload, ODataFormat format, long? count, Uri nextLink, bool request)
        {
            Action<ODataWriter> action = (odataWriter) =>
            {
                var feedToWrite = new ODataFeed { Id = new Uri("urn:feedId") };
                odataWriter.WriteStart(feedToWrite);
                    feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.EndAnnotation", PrimitiveValue1));
                    feedToWrite.Count = count;
                    feedToWrite.NextPageLink = nextLink;
                odataWriter.WriteEnd();
            };

            WriteAnnotationsAndValidatePayload(action, EntitySet, format, expectedPayload, request, createFeedWriter: true);
        }
 internal static TestMediaTypeWithFormat GetResponseTypeFromFormat(ODataFormat format, ODataVersion version)
 {
     return GetResponseType(version, s => s.SetContentType(format));
 }
        private void WriteAnnotationAtStartOnTopLevelEntry(IEdmNavigationSource navigationSource, ODataFormat format, string expectedPayload)
        {
            Action<ODataWriter> action = (odataWriter) =>
            {
                var entryToWrite = new ODataEntry {Properties = new[] {new ODataProperty {Name = "ID", Value = 1}}};
                entryToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("Custom.PrimitiveCollectionAnnotation", PrimitiveCollectionValue));
                odataWriter.WriteStart(entryToWrite);
                    var editLinkUri = tempUri;
                    entryToWrite.EditLink = editLinkUri;
                odataWriter.WriteEnd();
            };

            this.WriteAnnotationsAndValidatePayload(action, navigationSource, format, expectedPayload, request: false, createFeedWriter: false);
            this.WriteAnnotationsAndValidatePayload(action, navigationSource, format, expectedPayload, request: true, createFeedWriter: false);
        }
 public static FormatQueryPart Format(ODataFormat format)
 {
     return new FormatQueryPart(format);
 }
 public TestODataOutputContext(ODataFormat format, ODataMessageWriterSettings messageWriterSettings, bool writingResponse, bool synchronous, IEdmModel model, IODataUrlResolver urlResolver)
     :base(format, messageWriterSettings, writingResponse, synchronous, model, urlResolver)
 {
 }
 /// <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;
 }
        /// <summary>
        /// Create JSON output context.
        /// </summary>
        /// <param name="format">The format to create the output context for.</param>
        /// <param name="jsonWriter">The JSON writer to write to.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        /// <returns>The newly created output context.</returns>
        /// <remarks>This method is for writing the output directly to the JSON writer, when created with this method
        /// the output context doesn't support most of the methods on it. Note that Dispose will do nothing in this case.</remarks>
        internal static ODataJsonOutputContext Create(
            ODataFormat format,
            JsonWriter jsonWriter,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(format == ODataFormat.VerboseJson, "This method only supports the verbose JSON format.");
            Debug.Assert(jsonWriter != null, "jsonWriter != null");
            Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");

            return new ODataJsonOutputContext(
                format,
                jsonWriter,
                messageWriterSettings,
                writingResponse,
                true,
                model,
                urlResolver);
        }
        /// <summary>
        /// Create ATOM output context.
        /// </summary>
        /// <param name="format">The format to create the output context for.</param>
        /// <param name="message">The message to use.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        /// <returns>The newly created output context.</returns>
        internal static ODataOutputContext Create(
            ODataFormat format,
            ODataMessage message,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(format == ODataFormat.Atom, "This method only supports the ATOM format.");
            Debug.Assert(message != null, "message != null");
            Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");

            Stream messageStream = message.GetStream();
            return new ODataAtomOutputContext(
                format,
                messageStream,
                encoding,
                messageWriterSettings,
                writingResponse,
                true,
                model,
                urlResolver);
        }
        private void WriteAnnotationAtEndExpandedFeedShouldFail(ODataFormat format)
        {
            Action<ODataWriter> action = (odataWriter) =>
            {
                var entryToWrite = new ODataEntry {Properties = new[] {new ODataProperty {Name = "ID", Value = 1}}};
                odataWriter.WriteStart(entryToWrite);

                ODataNavigationLink navLink = new ODataNavigationLink {Name = "ResourceSetNavigationProperty", Url = new Uri("http://service/navLink", UriKind.RelativeOrAbsolute),  IsCollection = true};
                odataWriter.WriteStart(navLink);

                var feedToWrite = new ODataFeed { Id = new Uri("urn:feedId") };
                odataWriter.WriteStart(feedToWrite);

                feedToWrite.InstanceAnnotations.Add(new ODataInstanceAnnotation("custom.StartFeedAnnotation", PrimitiveValue1));
                odataWriter.WriteEnd();
            };

            Action testResponse = () => this.WriteAnnotationsAndValidatePayload(action, EntitySet, format, null, request: false, createFeedWriter: false);
            testResponse.ShouldThrow<ODataException>().WithMessage(Strings.ODataJsonLightWriter_InstanceAnnotationNotSupportedOnExpandedFeed);

            Action testResponseOfSingleton = () => this.WriteAnnotationsAndValidatePayload(action, Singleton, format, null, request: false, createFeedWriter: false);
            testResponseOfSingleton.ShouldThrow<ODataException>().WithMessage(Strings.ODataJsonLightWriter_InstanceAnnotationNotSupportedOnExpandedFeed);                

            Action testRequest = () => this.WriteAnnotationsAndValidatePayload(action, EntitySet, format, null, request: true, createFeedWriter: false);
            testRequest.ShouldThrow<ODataException>().WithMessage(Strings.ODataJsonLightWriter_InstanceAnnotationNotSupportedOnExpandedFeed);

            Action testRequestOfSingleton = () => this.WriteAnnotationsAndValidatePayload(action, Singleton, format, null, request: true, createFeedWriter: false);
            testRequestOfSingleton.ShouldThrow<ODataException>().WithMessage(Strings.ODataJsonLightWriter_InstanceAnnotationNotSupportedOnExpandedFeed);                                
        }
        private static TestODataWriterCore CreateODataWriterCore(ODataFormat format, bool writingResponse, IEdmModel model, IEdmEntitySet writerSet, IEdmEntityType writerEntityType, bool writeFeed)
        {
            var resolver = new TestUrlResolver();
            var settings = new ODataMessageWriterSettings { DisableMessageStreamDisposal = true, Version = ODataVersion.V4 };
            settings.SetServiceDocumentUri(new Uri("http://example.com"));

            var outputContext = new TestODataOutputContext(format, settings, writingResponse, false, model, resolver);
            return new TestODataWriterCore(outputContext, writerSet, writerEntityType, writeFeed);
        }
        /// <summary>
        /// Asynchronously create ATOM output context.
        /// </summary>
        /// <param name="format">The format to create the output context for.</param>
        /// <param name="message">The message to use.</param>
        /// <param name="encoding">The encoding to use.</param>
        /// <param name="messageWriterSettings">Configuration settings of the OData writer.</param>
        /// <param name="writingResponse">true if writing a response message; otherwise false.</param>
        /// <param name="model">The model to use.</param>
        /// <param name="urlResolver">The optional URL resolver to perform custom URL resolution for URLs written to the payload.</param>
        /// <returns>Task which when completed returns the newly created output context.</returns>
        internal static Task<ODataOutputContext> CreateAsync(
            ODataFormat format,
            ODataMessage message,
            Encoding encoding,
            ODataMessageWriterSettings messageWriterSettings,
            bool writingResponse,
            IEdmModel model,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(format == ODataFormat.Atom, "This method only supports the ATOM format.");
            Debug.Assert(message != null, "message != null");
            Debug.Assert(messageWriterSettings != null, "messageWriterSettings != null");

            return message.GetStreamAsync()
                .FollowOnSuccessWith(
                    (streamTask) => (ODataOutputContext)new ODataAtomOutputContext(
                        format,
                        streamTask.Result,
                        encoding,
                        messageWriterSettings,
                        writingResponse,
                        false,
                        model,
                        urlResolver));
        }