コード例 #1
0
        /// <summary>
        /// Asynchronously writes the headers, (optional) Content-ID and the request line.
        /// </summary>
        /// <param name="writer">Writer to write to.</param>
        /// <param name="httpMethod">The Http method to be used for this request operation.</param>
        /// <param name="uri">The Uri to be used for this request operation.</param>
        /// <param name="baseUri">The service root Uri to be used for this request operation.</param>
        /// <param name="inChangesetBound">Whether we are in changeset bound.</param>
        /// <param name="contentId">The Content-ID value to write in changeset head.</param>
        /// <param name="payloadUriOption">The format of operation Request-URI, which could be AbsoluteUri, AbsoluteResourcePathAndHost, or RelativeResourcePath.</param>
        /// <returns>A task that represents the asynchronous write operation.</returns>
        internal static async Task WriteRequestPreambleAsync(
            TextWriter writer,
            string httpMethod,
            Uri uri,
            Uri baseUri,
            bool inChangesetBound,
            string contentId,
            BatchPayloadUriOption payloadUriOption)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(uri != null, "uri != null");
            Debug.Assert(uri.IsAbsoluteUri || UriUtils.UriToString(uri).StartsWith("$", StringComparison.Ordinal), "uri.IsAbsoluteUri || uri.OriginalString.StartsWith(\"$\")");

            // Write the headers
            await WriteHeadersAsync(writer, inChangesetBound, contentId)
            .ConfigureAwait(false);

            // Write separator line between headers and the request line
            await writer.WriteLineAsync()
            .ConfigureAwait(false);

            // Write request line
            await WriteRequestUriAsync(writer, httpMethod, uri, baseUri, payloadUriOption)
            .ConfigureAwait(false);
        }
コード例 #2
0
        /// <summary>
        /// Creates an <see cref="ODataBatchOperationRequestMessage"/> for writing an operation of a batch request
        /// - implementation of the actual functionality.
        /// </summary>
        /// <param name="method">The Http method to be used for this request operation.</param>
        /// <param name="uri">The Uri to be used for this request operation.</param>
        /// <param name="contentId">The Content-ID value to write in ChangeSet head.</param>
        /// <param name="payloadUriOption">
        /// The format of operation Request-URI, which could be AbsoluteUri, AbsoluteResourcePathAndHost, or RelativeResourcePath.</param>
        /// <param name="dependsOnIds">The prerequisite request ids of this request. By default its value should be null for Multipart/Mixed
        /// format and the dependsOnIds implicitly derived per the protocol will be used; Otherwise, non-null will be used as override after
        /// validation.</param>
        /// <returns>The message that can be used to write the request operation.</returns>
        protected override ODataBatchOperationRequestMessage CreateOperationRequestMessageImplementation(
            string method, Uri uri, string contentId, BatchPayloadUriOption payloadUriOption,
            IEnumerable <string> dependsOnIds)
        {
            // write pending message data (headers, response line) for a previously unclosed message/request
            this.WritePendingMessageData(true);

            // create the new request operation
            // For Multipart batch format, validate dependsOnIds if it is user explicit input, otherwise skip validation
            // when it is implicitly derived per protocol.
            ODataBatchOperationRequestMessage operationRequestMessage = BuildOperationRequestMessage(
                this.RawOutputContext.OutputStream,
                method, uri, contentId,
                this.changeSetBoundary,
                dependsOnIds);

            this.SetState(BatchWriterState.OperationCreated);

            // write the operation's start boundary string
            this.WriteStartBoundaryForOperation();

            if (contentId != null)
            {
                this.dependsOnIdsTracker.AddDependsOnId(contentId);
            }

            // write the headers and request line
            ODataMultipartMixedBatchWriterUtils.WriteRequestPreamble(this.RawOutputContext.TextWriter, method, uri,
                                                                     this.RawOutputContext.MessageWriterSettings.BaseUri, changeSetBoundary != null, contentId,
                                                                     payloadUriOption);

            return(operationRequestMessage);
        }
コード例 #3
0
        private void WriteRequestUri(Uri uri, BatchPayloadUriOption payloadUriOption)
        {
            this.jsonWriter.WriteName(PropertyUrl);

            if (uri.IsAbsoluteUri)
            {
                Uri    baseUri           = this.OutputContext.MessageWriterSettings.BaseUri;
                string absoluteUriString = uri.AbsoluteUri;

                switch (payloadUriOption)
                {
                case BatchPayloadUriOption.AbsoluteUri:
                    this.jsonWriter.WriteValue(UriUtils.UriToString(uri));
                    break;

                case BatchPayloadUriOption.AbsoluteUriUsingHostHeader:
                    string absoluteResourcePath = absoluteUriString.Substring(absoluteUriString.IndexOf('/', absoluteUriString.IndexOf("//", StringComparison.Ordinal) + 2));
                    this.jsonWriter.WriteValue(absoluteResourcePath);
                    this.CurrentOperationRequestMessage.SetHeader("host", string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}:{1}", uri.Host, uri.Port));
                    break;

                case BatchPayloadUriOption.RelativeUri:
                    Debug.Assert(baseUri != null, "baseUri != null");
                    string baseUriString = UriUtils.UriToString(baseUri);
                    Debug.Assert(uri.AbsoluteUri.StartsWith(baseUriString, StringComparison.Ordinal), "absoluteUriString.StartsWith(baseUriString)");
                    string relativeResourcePath = uri.AbsoluteUri.Substring(baseUriString.Length);
                    this.jsonWriter.WriteValue(relativeResourcePath);
                    break;
                }
            }
            else
            {
                this.jsonWriter.WriteValue(UriUtils.UriToString(uri));
            }
        }
コード例 #4
0
        /// <summary>
        /// Writes the headers, (optional) Content-ID and the request line.
        /// </summary>
        /// <param name="writer">Writer to write to.</param>
        /// <param name="httpMethod">The Http method to be used for this request operation.</param>
        /// <param name="uri">The Uri to be used for this request operation.</param>
        /// <param name="baseUri">The service root Uri to be used for this request operation.</param>
        /// <param name="inChangeSetBound">Whether we are in ChangeSetBound.</param>
        /// <param name="contentId">The Content-ID value to write in ChangeSet head.</param>
        /// <param name="payloadUriOption">The format of operation Request-URI, which could be AbsoluteUri, AbsoluteResourcePathAndHost, or RelativeResourcePath.</param>
        internal static void WriteRequestPreamble(
            TextWriter writer,
            string httpMethod,
            Uri uri,
            Uri baseUri,
            bool inChangeSetBound,
            string contentId,
            BatchPayloadUriOption payloadUriOption)
        {
            Debug.Assert(writer != null, "writer != null");
            Debug.Assert(uri != null, "uri != null");
            Debug.Assert(uri.IsAbsoluteUri || UriUtils.UriToString(uri).StartsWith("$", StringComparison.Ordinal), "uri.IsAbsoluteUri || uri.OriginalString.StartsWith(\"$\")");

            // write the headers
            WriteHeaders(writer, inChangeSetBound, contentId);

            // write separator line between headers and the request line
            writer.WriteLine();

            // write request line
            WriteRequestUri(writer, httpMethod, uri, baseUri, payloadUriOption);
        }
コード例 #5
0
        /// <summary>
        /// Creates an <see cref="ODataBatchOperationRequestMessage"/> for writing an operation of a batch request
        /// - implementation of the actual functionality.
        /// </summary>
        /// <param name="method">The Http method to be used for this request operation.</param>
        /// <param name="uri">The Uri to be used for this request operation.</param>
        /// <param name="contentId">The Content-ID value to write in ChangeSet head.</param>
        /// <param name="payloadUriOption">
        /// The format of operation Request-URI, which could be AbsoluteUri, AbsoluteResourcePathAndHost, or RelativeResourcePath.</param>
        /// <param name="dependsOnIds">The prerequisite request ids of this request.</param>
        /// <returns>The message that can be used to write the request operation.</returns>
        protected override ODataBatchOperationRequestMessage CreateOperationRequestMessageImplementation(
            string method, Uri uri, string contentId, BatchPayloadUriOption payloadUriOption,
            IEnumerable<string> dependsOnIds)
        {
            // write pending message data (headers, response line) for a previously unclosed message/request
            this.WritePendingMessageData(true);

            // create the new request operation
            ODataBatchOperationRequestMessage operationRequestMessage = BuildOperationRequestMessage(
                this.RawOutputContext.OutputStream,
                method, uri, contentId, /*groupId*/null, dependsOnIds, ODataFormat.Batch);

            this.SetState(BatchWriterState.OperationCreated);

            // write the operation's start boundary string
            this.WriteStartBoundaryForOperation();

            // write the headers and request line
            ODataMultipartMixedBatchWriterUtils.WriteRequestPreamble(this.RawOutputContext.TextWriter, method, uri,
                this.RawOutputContext.MessageWriterSettings.BaseUri, changeSetBoundary != null, contentId,
                payloadUriOption);

            return operationRequestMessage;
        }
コード例 #6
0
        private void BatchRequestWithPayloadUriWritingOption(BatchPayloadUriOption option)
        {
            var writerSettings = new ODataMessageWriterSettings();

            writerSettings.BaseUri = ServiceBaseUri;
            ODataMessageReaderSettings readerSettings = new ODataMessageReaderSettings()
            {
                BaseUri = ServiceBaseUri
            };

            var accountType                = Model.FindDeclaredType(NameSpacePrefix + "Account") as IEdmEntityType;
            var accountSet                 = Model.EntityContainer.FindEntitySet("Accounts");
            var paymentInstrumentType      = Model.FindDeclaredType(NameSpacePrefix + "PaymentInstrument") as IEdmEntityType;
            IEdmNavigationProperty navProp = accountType.FindProperty("MyPaymentInstruments") as IEdmNavigationProperty;
            var myPaymentInstrumentSet     = accountSet.FindNavigationTarget(navProp);

            var requestMessage = new HttpWebRequestMessage(new Uri(ServiceBaseUri + "$batch"));

            requestMessage.SetHeader("Content-Type", "multipart/mixed;boundary=batch_01AD6766-4A45-47CC-9463-94D4591D8DA9");
            requestMessage.SetHeader("OData-Version", "4.0");
            requestMessage.Method = "POST";

            using (var messageWriter = new ODataMessageWriter(requestMessage, writerSettings, Model))
            {
                var batchWriter = messageWriter.CreateODataBatchWriter();

                //Batch start.
                batchWriter.WriteStartBatch();

                //A Get request.

                var batchOperation1 = batchWriter.CreateOperationRequestMessage("GET", new Uri(ServiceBaseUri + "Accounts(101)/MyPaymentInstruments"), null, option);
                batchOperation1.SetHeader("Accept", "application/json;odata.metadata=full");
                //Get request ends.

                //Changeset start.
                batchWriter.WriteStartChangeset();

                //The first operation in changeset is a Create request.

                ODataBatchOperationRequestMessage batchChangesetOperation1 = batchWriter.CreateOperationRequestMessage("POST", new Uri(ServiceBaseUri + "Accounts(102)/MyPaymentInstruments"), "1", option);
                batchChangesetOperation1.SetHeader("Content-Type", "application/json;odata.metadata=full");
                batchChangesetOperation1.SetHeader("Accept", "application/json;odata.metadata=full");
                var paymentInstrumentEntry = new ODataResource()
                {
                    TypeName = NameSpacePrefix + "PaymentInstrument"
                };
                var paymentInstrumentEntryP1 = new ODataProperty {
                    Name = "PaymentInstrumentID", Value = 102910
                };
                var paymentInstrumentEntryP2 = new ODataProperty {
                    Name = "FriendlyName", Value = "102 batch new PI"
                };
                var paymentInstrumentEntryP3 = new ODataProperty {
                    Name = "CreatedDate", Value = new DateTimeOffset(new DateTime(2013, 12, 29, 11, 11, 57))
                };
                paymentInstrumentEntry.Properties = new[] { paymentInstrumentEntryP1, paymentInstrumentEntryP2, paymentInstrumentEntryP3 };

                using (var entryMessageWriter = new ODataMessageWriter(batchChangesetOperation1, writerSettings, Model))
                {
                    var odataEntryWriter = entryMessageWriter.CreateODataResourceWriter(myPaymentInstrumentSet, paymentInstrumentType);
                    odataEntryWriter.WriteStart(paymentInstrumentEntry);
                    odataEntryWriter.WriteEnd();
                }

                //Changeset end.
                batchWriter.WriteEndChangeset();

                //Another Get request.

                var batchOperation2 = batchWriter.CreateOperationRequestMessage("GET", new Uri(ServiceBaseUri + "Accounts(103)/MyPaymentInstruments(103901)/BillingStatements(103901001)"), null, option);
                batchOperation2.SetHeader("Accept", "application/json;odata.metadata=full");

                //Batch end.
                batchWriter.WriteEndBatch();
            }

            var responseMessage = requestMessage.GetResponse();

            Assert.AreEqual(200, responseMessage.StatusCode);

            using (var innerMessageReader = new ODataMessageReader(responseMessage, readerSettings, Model))
            {
                var batchReader      = innerMessageReader.CreateODataBatchReader();
                int batchOperationId = 0;

                while (batchReader.Read())
                {
                    switch (batchReader.State)
                    {
                    case ODataBatchReaderState.Initial:
                        break;

                    case ODataBatchReaderState.ChangesetStart:
                        break;

                    case ODataBatchReaderState.ChangesetEnd:
                        break;

                    case ODataBatchReaderState.Operation:
                        ODataBatchOperationResponseMessage operationResponse = batchReader.CreateOperationResponseMessage();

                        using (var operationResponseReader = new ODataMessageReader(operationResponse, readerSettings, Model))
                        {
                            if (batchOperationId == 0)
                            {
                                // the first response message is a feed
                                var feedReader = operationResponseReader.CreateODataResourceSetReader();

                                Assert.AreEqual(200, operationResponse.StatusCode);
                                List <ODataResource> pis = new List <ODataResource>();
                                while (feedReader.Read())
                                {
                                    switch (feedReader.State)
                                    {
                                    case ODataReaderState.ResourceEnd:
                                        ODataResource entry = feedReader.Item as ODataResource;
                                        Assert.IsNotNull(entry);
                                        pis.Add(entry);
                                        break;
                                    }
                                }
                                Assert.AreEqual(ODataReaderState.Completed, feedReader.State);
                                Assert.AreEqual(3, pis.Count);
                            }
                            else if (batchOperationId == 1)
                            {
                                // the second response message is a creation response
                                var entryReader = operationResponseReader.CreateODataResourceReader();

                                Assert.AreEqual(201, operationResponse.StatusCode);
                                List <ODataResource> pis = new List <ODataResource>();
                                while (entryReader.Read())
                                {
                                    switch (entryReader.State)
                                    {
                                    case ODataReaderState.ResourceEnd:
                                        ODataResource entry = entryReader.Item as ODataResource;
                                        Assert.IsNotNull(entry);
                                        pis.Add(entry);
                                        break;
                                    }
                                }
                                Assert.AreEqual(ODataReaderState.Completed, entryReader.State);
                                Assert.AreEqual(1, pis.Count);
                                Assert.AreEqual(102910, pis[0].Properties.Single(p => p.Name == "PaymentInstrumentID").Value);
                            }
                            else if (batchOperationId == 2)
                            {
                                // the third response message is an entry
                                var entryReader = operationResponseReader.CreateODataResourceReader();

                                Assert.AreEqual(200, operationResponse.StatusCode);
                                List <ODataResource> statements = new List <ODataResource>();
                                while (entryReader.Read())
                                {
                                    switch (entryReader.State)
                                    {
                                    case ODataReaderState.ResourceEnd:
                                        ODataResource entry = entryReader.Item as ODataResource;
                                        Assert.IsNotNull(entry);
                                        statements.Add(entry);
                                        break;
                                    }
                                }
                                Assert.AreEqual(ODataReaderState.Completed, entryReader.State);
                                Assert.AreEqual(1, statements.Count);
                                Assert.AreEqual(103901001, statements[0].Properties.Single(p => p.Name == "StatementID").Value);
                            }
                        }
                        batchOperationId++;
                        break;
                    }
                }
                Assert.AreEqual(ODataBatchReaderState.Completed, batchReader.State);
            }
        }
コード例 #7
0
        private byte[] ClientWriteAsyncBatchRequest(BatchPayloadUriOption payloadUriOption)
        {
            var stream = new MemoryStream();

            IODataRequestMessage requestMessage = new InMemoryMessage {
                Stream = stream
            };

            requestMessage.SetHeader("Content-Type", batchContentType);

            using (var messageWriter = new ODataMessageWriter(requestMessage, new ODataMessageWriterSettings {
                BaseUri = new Uri(serviceDocumentUri)
            }))
            {
                var batchWriter = messageWriter.CreateODataBatchWriter();

                batchWriter.WriteStartBatch();

                // Write a query operation.
                var queryOperationMessage = batchWriter.CreateOperationRequestMessage("GET", new Uri(serviceDocumentUri + "/Customers('ALFKI')"), /*contentId*/ null, payloadUriOption);

                // Write a changeset with multi update operation.
                batchWriter.WriteStartChangeset();

                // Create a creation operation in the changeset.
                var updateOperationMessage = batchWriter.CreateOperationRequestMessage("POST", new Uri(serviceDocumentUri + "/Customers"), "1", payloadUriOption);

                // Use a new message writer to write the body of this operation.
                using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage))
                {
                    var entryWriter = operationMessageWriter.CreateODataResourceWriter();
                    var entry       = new ODataResource()
                    {
                        TypeName = "MyNS.Customer", Properties = new[] { new ODataProperty()
                                                                         {
                                                                             Name = "Id", Value = "AFKIL"
                                                                         }, new ODataProperty()
                                                                         {
                                                                             Name = "Name", Value = "Bob"
                                                                         } }
                    };
                    entryWriter.WriteStart(entry);
                    entryWriter.WriteEnd();
                }

                updateOperationMessage = batchWriter.CreateOperationRequestMessage("PATCH", new Uri(serviceDocumentUri + "/Customers('ALFKI')"), "2", payloadUriOption);

                using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage))
                {
                    var entryWriter = operationMessageWriter.CreateODataResourceWriter();
                    var entry       = new ODataResource()
                    {
                        TypeName = "MyNS.Customer", Properties = new[] { new ODataProperty()
                                                                         {
                                                                             Name = "Name", Value = "Jack"
                                                                         } }
                    };
                    entryWriter.WriteStart(entry);
                    entryWriter.WriteEnd();
                }

                batchWriter.WriteEndChangeset();

                // Write a query operation.
                batchWriter.CreateOperationRequestMessage("GET", new Uri(serviceDocumentUri + "/Products"), /*contentId*/ null, payloadUriOption);

                batchWriter.WriteEndBatch();

                stream.Position = 0;
                return(stream.ToArray());
            }
        }
コード例 #8
0
        /// <summary>
        /// Writes the request line.
        /// </summary>
        /// <param name="writer">Writer to write request uri.</param>
        /// <param name="httpMethod">The Http method to be used for this request operation.</param>
        /// <param name="uri">The Uri to be used for this request operation.</param>
        /// <param name="baseUri">The service root Uri to be used for this request operation.</param>
        /// <param name="payloadUriOption">The format of operation Request-URI, which could be AbsoluteUri, AbsoluteResourcePathAndHost, or RelativeResourcePath.</param>
        private static void WriteRequestUri(TextWriter writer, string httpMethod, Uri uri, Uri baseUri, BatchPayloadUriOption payloadUriOption)
        {
            if (uri.IsAbsoluteUri)
            {
                string absoluteUriString = uri.AbsoluteUri;

                switch (payloadUriOption)
                {
                case BatchPayloadUriOption.AbsoluteUri:
                    writer.WriteLine("{0} {1} {2}", httpMethod, UriUtils.UriToString(uri), ODataConstants.HttpVersionInBatching);
                    break;

                case BatchPayloadUriOption.AbsoluteUriUsingHostHeader:
                    string absoluteResourcePath = absoluteUriString.Substring(absoluteUriString.IndexOf('/', absoluteUriString.IndexOf("//", StringComparison.Ordinal) + 2));
                    writer.WriteLine("{0} {1} {2}", httpMethod, absoluteResourcePath, ODataConstants.HttpVersionInBatching);
                    writer.WriteLine("Host: {0}:{1}", uri.Host, uri.Port);
                    break;

                case BatchPayloadUriOption.RelativeUri:
                    Debug.Assert(baseUri != null, "baseUri != null");
                    string baseUriString = UriUtils.UriToString(baseUri);
                    Debug.Assert(absoluteUriString.StartsWith(baseUriString, StringComparison.Ordinal), "absoluteUriString.StartsWith(baseUriString)");
                    string relativeResourcePath = absoluteUriString.Substring(baseUriString.Length);
                    writer.WriteLine("{0} {1} {2}", httpMethod, relativeResourcePath, ODataConstants.HttpVersionInBatching);
                    break;
                }
            }
            else
            {
                writer.WriteLine("{0} {1} {2}", httpMethod, UriUtils.UriToString(uri), ODataConstants.HttpVersionInBatching);
            }
        }
コード例 #9
0
        /// <summary>
        /// Creates an <see cref="ODataBatchOperationRequestMessage"/> for writing an operation of a
        /// batch request - implementation of the actual functionality.
        /// </summary>
        /// <param name="method">The Http method to be used for this request operation.</param>
        /// <param name="uri">The Uri to be used for this request operation.</param>
        /// <param name="contentId">The Content-ID value to write in ChangeSet head.</param>
        /// <param name="payloadUriOption">
        /// The format of operation Request-URI, which could be AbsoluteUri, AbsoluteResourcePathAndHost, or RelativeResourcePath.</param>
        /// <param name="dependsOnIds">The prerequisite request ids of this request.</param>
        /// <returns>The message that can be used to write the request operation.</returns>
        protected override ODataBatchOperationRequestMessage CreateOperationRequestMessageImplementation(string method,
                                                                                                         Uri uri, string contentId, BatchPayloadUriOption payloadUriOption, IEnumerable <string> dependsOnIds)
        {
            // write pending message data (headers, request line) for a previously unclosed message/request
            this.WritePendingMessageData(true);

            // For json batch request, content Id is required for single request or request within atomicityGroup.
            if (contentId == null)
            {
                contentId = Guid.NewGuid().ToString();
            }

            AddGroupIdLookup(contentId);

            // create the new request operation
            this.CurrentOperationRequestMessage = BuildOperationRequestMessage(
                this.JsonLightOutputContext.GetOutputStream(), method, uri, contentId,
                this.atomicityGroupId, dependsOnIds, ODataFormat.Json);

            this.SetState(BatchWriterState.OperationCreated);

            // write the operation's start boundary string
            this.WriteStartBoundaryForOperation();

            this.jsonWriter.WriteName(PropertyId);
            this.jsonWriter.WriteValue(contentId);

            if (this.atomicityGroupId != null)
            {
                this.jsonWriter.WriteName(PropertyAtomicityGroup);
                this.jsonWriter.WriteValue(this.atomicityGroupId);
            }

            if (this.CurrentOperationRequestMessage.DependsOnIds != null &&
                this.CurrentOperationRequestMessage.DependsOnIds.Any())
            {
                this.jsonWriter.WriteName(PropertyDependsOn);
                this.jsonWriter.StartArrayScope();

                foreach (string dependsOnId in this.CurrentOperationRequestMessage.DependsOnIds)
                {
                    ValidateDependsOnId(contentId, dependsOnId);
                    this.jsonWriter.WriteValue(dependsOnId);
                }

                this.jsonWriter.EndArrayScope();
            }

            this.jsonWriter.WriteName(PropertyMethod);
            this.jsonWriter.WriteValue(method);

            this.jsonWriter.WriteName(PropertyUrl);
            this.jsonWriter.WriteValue(UriUtils.UriToString(uri));

            return(this.CurrentOperationRequestMessage);
        }
コード例 #10
0
        /// <summary>
        /// Asynchronously writes the request line.
        /// </summary>
        /// <param name="writer">Writer to write request uri.</param>
        /// <param name="httpMethod">The Http method to be used for this request operation.</param>
        /// <param name="uri">The Uri to be used for this request operation.</param>
        /// <param name="baseUri">The service root Uri to be used for this request operation.</param>
        /// <param name="payloadUriOption">The format of operation Request-URI, which could be AbsoluteUri, AbsoluteResourcePathAndHost, or RelativeResourcePath.</param>
        /// <returns>A task that represents the asynchronous write operation.</returns>
        private static async Task WriteRequestUriAsync(TextWriter writer, string httpMethod, Uri uri, Uri baseUri, BatchPayloadUriOption payloadUriOption)
        {
            if (uri.IsAbsoluteUri)
            {
                string absoluteUriString = uri.AbsoluteUri;

                switch (payloadUriOption)
                {
                case BatchPayloadUriOption.AbsoluteUri:
                    await writer.WriteLineAsync(string.Concat(httpMethod, " ", UriUtils.UriToString(uri), " ", ODataConstants.HttpVersionInBatching))
                    .ConfigureAwait(false);

                    break;

                case BatchPayloadUriOption.AbsoluteUriUsingHostHeader:
                    string absoluteResourcePath = ExtractAbsoluteResourcePath(absoluteUriString);

                    await writer.WriteLineAsync(string.Concat(httpMethod, " ", absoluteResourcePath, " ", ODataConstants.HttpVersionInBatching))
                    .ConfigureAwait(false);

                    await writer.WriteLineAsync(string.Concat("Host: ", uri.Host, ":", uri.Port))
                    .ConfigureAwait(false);

                    break;

                case BatchPayloadUriOption.RelativeUri:
                    Debug.Assert(baseUri != null, "baseUri != null");
                    string baseUriString = UriUtils.UriToString(baseUri);

                    Debug.Assert(absoluteUriString.StartsWith(baseUriString, StringComparison.Ordinal), "absoluteUriString.StartsWith(baseUriString)");
                    string relativeResourcePath = absoluteUriString.Substring(baseUriString.Length);

                    await writer.WriteLineAsync(string.Concat(httpMethod, " ", relativeResourcePath, " ", ODataConstants.HttpVersionInBatching))
                    .ConfigureAwait(false);

                    break;
                }
            }
            else
            {
                await writer.WriteLineAsync(string.Concat(httpMethod, " ", UriUtils.UriToString(uri), " ", ODataConstants.HttpVersionInBatching))
                .ConfigureAwait(false);
            }
        }