Example #1
0
        public async Task WriteResponse_SynchronouslyWritesChangeSet()
        {
            HttpResponseMessage[] responses = new HttpResponseMessage[]
            {
                new HttpResponseMessage(HttpStatusCode.Accepted),
                new HttpResponseMessage(HttpStatusCode.NoContent)
            };
            ChangeSetResponseItem responseItem    = new ChangeSetResponseItem(responses);
            MemoryStream          memoryStream    = new MemoryStream();
            IODataResponseMessage responseMessage = new ODataMessageWrapper(memoryStream);
            ODataMessageWriter    writer          = new ODataMessageWriter(responseMessage);
            ODataBatchWriter      batchWriter     = writer.CreateODataBatchWriter();

            batchWriter.WriteStartBatch();

            // For backward compatibility, default is to assume a synchronous batch writer
            await responseItem.WriteResponseAsync(batchWriter, CancellationToken.None);

            batchWriter.WriteEndBatch();
            memoryStream.Position = 0;
            string responseString = new StreamReader(memoryStream).ReadToEnd();

            Assert.Contains("changesetresponse", responseString);
            Assert.Contains("Accepted", responseString);
            Assert.Contains("No Content", responseString);
        }
Example #2
0
        public void WriteResponseAsync_WritesChangeSet()
        {
            HttpResponseMessage[] responses = new HttpResponseMessage[]
            {
                new HttpResponseMessage(HttpStatusCode.Accepted),
                new HttpResponseMessage(HttpStatusCode.NoContent)
            };
            ChangeSetResponseItem responseItem    = new ChangeSetResponseItem(responses);
            MemoryStream          memoryStream    = new MemoryStream();
            IODataResponseMessage responseMessage = new ODataMessageWrapper(memoryStream);
            ODataMessageWriter    writer          = new ODataMessageWriter(responseMessage);
            ODataBatchWriter      batchWriter     = writer.CreateODataBatchWriter();

            batchWriter.WriteStartBatch();

            responseItem.WriteResponseAsync(batchWriter, CancellationToken.None).Wait();

            batchWriter.WriteEndBatch();
            memoryStream.Position = 0;
            string responseString = new StreamReader(memoryStream).ReadToEnd();

            Assert.Contains("changesetresponse", responseString);
            Assert.Contains("Accepted", responseString);
            Assert.Contains("No Content", responseString);
        }
        public void WriteMessageAsync_NullResponse_Throws()
        {
            HttpContent content = new StringContent(String.Empty, Encoding.UTF8, "multipart/mixed");
            content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("boundary", Guid.NewGuid().ToString()));
            IODataResponseMessage odataResponse = new ODataMessageWrapper(new MemoryStream(), content.Headers);
            ODataMessageWriter messageWriter = new ODataMessageWriter(odataResponse);

            Assert.ThrowsArgumentNull(
                () => ODataBatchResponseItem.WriteMessageAsync(messageWriter.CreateODataBatchWriter(), null).Wait(),
                "response");
        }
Example #4
0
        public async Task WriteMessageAsync_NullResponse_Throws()
        {
            HttpContent content = new StringContent(String.Empty, Encoding.UTF8, "multipart/mixed");

            content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("boundary", Guid.NewGuid().ToString()));
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(new MemoryStream(), content.Headers);
            ODataMessageWriter    messageWriter = new ODataMessageWriter(odataResponse);

            await ExceptionAssert.ThrowsArgumentNullAsync(
                () => ODataBatchResponseItem.WriteMessageAsync(messageWriter.CreateODataBatchWriter(), null, CancellationToken.None),
                "response");
        }
Example #5
0
        public string UpdateDataToOData(Change[] changes, string tableName, string[] headers)
        {
            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(this.odataEndpointURL, "$batch"));

            requestMessage.Headers.Add("DataServiceVersion", this.odataVersion);
            requestMessage.Headers.Add("MaxDataServiceVersion", this.odataMaxVersion);

            var setting = new ODataMessageWriterSettings();

            setting.SetContentType(ODataFormat.Batch);
            setting.BaseUri = this.odataEndpointURL;

            var odataHttpRequest = new ODataHttpRequest(requestMessage);
            var messageWriter    = new ODataMessageWriter(odataHttpRequest, setting, this.metadata);

            var batchWriter = messageWriter.CreateODataBatchWriter();

            batchWriter.WriteStartBatch();

            for (int i = 0; i < changes.Length; i++)
            {
                batchWriter.WriteStartChangeset();
                if (changes[i].operation == "DELETE")
                {
                    createDeleteOperationRequestMessage(ref batchWriter, changes[i], tableName);
                }

                if (changes[i].operation == "UPDATE")
                {
                    createUpdateOperationRequestMessage(ref batchWriter, changes[i], tableName, headers);
                }

                if (changes[i].operation == "INSERT")
                {
                    createInsertOperationRequestMessage(ref batchWriter, changes[i], tableName, headers);
                }

                batchWriter.WriteEndChangeset();
            }

            batchWriter.WriteEndBatch();
            batchWriter.Flush();
            odataHttpRequest.GetStream().Seek(0, SeekOrigin.Begin);

            HttpResponseMessage result = new HttpResponseMessage();

            using (HttpClient client = new HttpClient())
            {
                result = client.SendAsync(requestMessage).Result;
            }

            return(parseResponseMessage(result));
        }
        public void WriteMessageAsync_NullResponse_Throws()
        {
            HttpContent content = new StringContent(String.Empty, Encoding.UTF8, "multipart/mixed");

            content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("boundary", Guid.NewGuid().ToString()));
            IODataResponseMessage odataResponse = new ODataMessageWrapper(new MemoryStream(), content.Headers);
            ODataMessageWriter    messageWriter = new ODataMessageWriter(odataResponse);

            Assert.ThrowsArgumentNull(
                () => ODataBatchResponseItem.WriteMessageAsync(messageWriter.CreateODataBatchWriter(), null).Wait(),
                "response");
        }
#pragma warning disable 1998
        public override async Task StartBatchAsync()
        {
            _requestMessage = new ODataRequestMessage() { Url = _session.Settings.BaseUri };
            _messageWriter = new ODataMessageWriter(_requestMessage);
#if SILVERLIGHT
            _batchWriter = _messageWriter.CreateODataBatchWriter();
            _batchWriter.WriteStartBatch();
#else
            _batchWriter = await _messageWriter.CreateODataBatchWriterAsync();
            await _batchWriter.WriteStartBatchAsync();
#endif
        }
        private byte[] ClientWriteAsyncBatchRequest()
        {
            var stream = new MemoryStream();

            IODataRequestMessage requestMessage = new InMemoryMessage { Stream = stream };
            requestMessage.SetHeader("Content-Type", batchContentType);

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

                batchWriter.WriteStartBatch();

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

                // 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");

                // Use a new message writer to write the body of this operation.
                using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage))
                {
                    var entryWriter = operationMessageWriter.CreateODataEntryWriter();
                    var entry = new ODataEntry() { 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");

                using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage))
                {
                    var entryWriter = operationMessageWriter.CreateODataEntryWriter();
                    var entry = new ODataEntry() { 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);

                batchWriter.WriteEndBatch();

                stream.Position = 0;
                return stream.ToArray();
            }
        }
Example #9
0
        /// <summary>
        ///  Serialize the batch responses to an <see cref="IODataResponseMessage"/>.
        /// </summary>
        /// <param name="responseMessage">The response message.</param>
        /// <returns></returns>
        private async Task WriteToResponseMessageAsync(IODataResponseMessage responseMessage)
        {
            ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, _writerSettings);
            ODataBatchWriter   writer        = messageWriter.CreateODataBatchWriter();

            writer.WriteStartBatch();

            foreach (ODataBatchResponseItem response in Responses)
            {
                await response.WriteResponseAsync(writer);
            }

            writer.WriteEndBatch();
        }
        public async Task WriteMessageAsync_NullContext_Throws()
        {
            // Arrange
            HeaderDictionary headers = new HeaderDictionary
            {
                { "Content-Type", $"multipart/mixed;charset=utf-8;boundary={Guid.NewGuid()}" },
            };
            IODataResponseMessage odataResponse = ODataMessageWrapperHelper.Create(new MemoryStream(), headers);
            ODataMessageWriter    messageWriter = new ODataMessageWriter(odataResponse);

            // Act & Assert
            await ExceptionAssert.ThrowsArgumentNullAsync(
                () => ODataBatchResponseItem.WriteMessageAsync(messageWriter.CreateODataBatchWriter(), null), "context");
        }
Example #11
0
        /// <inheritdoc/>
        protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            IODataResponseMessage responseMessage = new ODataMessageWrapper(stream, Headers);
            ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage, _writerSettings);
            ODataBatchWriter writer = messageWriter.CreateODataBatchWriter();

            writer.WriteStartBatch();

            foreach (ODataBatchResponseItem response in Responses)
            {
                await response.WriteResponseAsync(writer, CancellationToken.None);
            }

            writer.WriteEndBatch();
        }
Example #12
0
        /// <inheritdoc/>
        protected override async Task SerializeToStreamAsync(Stream stream, TransportContext context)
        {
            IODataResponseMessage responseMessage = new ODataMessageWrapper(stream, Headers);
            ODataMessageWriter    messageWriter   = new ODataMessageWriter(responseMessage, _writerSettings);
            ODataBatchWriter      writer          = messageWriter.CreateODataBatchWriter();

            writer.WriteStartBatch();

            foreach (ODataBatchResponseItem response in Responses)
            {
                await response.WriteResponseAsync(writer, CancellationToken.None);
            }

            writer.WriteEndBatch();
        }
        private byte[] ClientWriteBatchRequest(BodyContentType bodyContentType)
        {
            MemoryStream stream = new MemoryStream();

            IODataRequestMessage requestMessage = new InMemoryMessage {
                Stream = stream
            };

            requestMessage.SetHeader(ODataConstants.ContentTypeHeader, batchContentTypeApplicationJson);

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage))
            {
                ODataBatchWriter batchWriter = messageWriter.CreateODataBatchWriter();

                batchWriter.WriteStartBatch();

                // Write a change set with update operation.
                batchWriter.WriteStartChangeset();

                // Create an update operation in the change set.
                ODataBatchOperationRequestMessage updateOperationMessage = batchWriter.CreateOperationRequestMessage(
                    "PUT", new Uri(serviceDocumentUri + "MyBlob"), "1");

                // Set the content type with explicit character set so that the content string
                // is flushed into the operation message body stream without byte-order-mark.
                updateOperationMessage.SetHeader("CoNtEnt-TYPE", GetContentType(bodyContentType));

                // Use the message writer to write encoded string content.
                using (ODataMessageWriter operationMessageWriter = new ODataMessageWriter(updateOperationMessage))
                {
                    operationMessageWriter.WriteValue(GetEncodedContentObject(bodyContentType, /*forRequest*/ true));
                }

                batchWriter.WriteEndChangeset();

                // Write a query operation.
                ODataBatchOperationRequestMessage queryOperationMessage = batchWriter.CreateOperationRequestMessage(
                    "GET", new Uri(serviceDocumentUri + "MyBlob"), /*contentId*/ null);

                // Header modification on inner payload.
                queryOperationMessage.SetHeader("AcCePt", GetContentType(bodyContentType));

                batchWriter.WriteEndBatch();

                stream.Position = 0;
                return(stream.ToArray());
            }
        }
Example #14
0
        public override async Task StartBatchAsync()
        {
            _requestMessage = new ODataRequestMessage()
            {
                Url = new Uri(_session.Settings.UrlBase)
            };
            _messageWriter = new ODataMessageWriter(_requestMessage);
#if SILVERLIGHT
            _batchWriter = _messageWriter.CreateODataBatchWriter();
            _batchWriter.WriteStartBatch();
#else
            _batchWriter = await _messageWriter.CreateODataBatchWriterAsync();

            await _batchWriter.WriteStartBatchAsync();
#endif
        }
Example #15
0
        public void Write(Stream stream, OeBatchMessage batchMessage)
        {
            IODataResponseMessage responseMessage = new OeInMemoryMessage(stream, batchMessage.ContentType);
            var settings = new ODataMessageWriterSettings()
            {
                Version = ODataVersion.V4,
                EnableMessageStreamDisposal = false,
                MessageQuotas = new ODataMessageQuotas()
            };
            var messageWriter       = new ODataMessageWriter(responseMessage, settings);
            ODataBatchWriter writer = messageWriter.CreateODataBatchWriter();

            writer.WriteStartBatch();
            WriteBatch(writer, batchMessage);
            writer.WriteEndBatch();
        }
#pragma warning disable 1998
        public override async Task StartBatchAsync()
        {
            _requestMessage = new ODataRequestMessage()
            {
                Url = _session.Settings.BaseUri
            };
            _messageWriter = new ODataMessageWriter(_requestMessage);
#if SILVERLIGHT
            _batchWriter = _messageWriter.CreateODataBatchWriter();
            _batchWriter.WriteStartBatch();
#else
            _batchWriter = await _messageWriter.CreateODataBatchWriterAsync();

            await _batchWriter.WriteStartBatchAsync();
#endif
            this.HasOperations = true;
        }
        public void WriteResponseAsync_WritesOperation()
        {
            OperationResponseItem responseItem = new OperationResponseItem(new HttpResponseMessage(HttpStatusCode.Accepted));
            MemoryStream memoryStream = new MemoryStream();
            IODataResponseMessage responseMessage = new ODataMessageWrapper(memoryStream);
            ODataMessageWriter writer = new ODataMessageWriter(responseMessage);
            ODataBatchWriter batchWriter = writer.CreateODataBatchWriter();
            batchWriter.WriteStartBatch();

            responseItem.WriteResponseAsync(batchWriter, CancellationToken.None).Wait();

            batchWriter.WriteEndBatch();
            memoryStream.Position = 0;
            string responseString = new StreamReader(memoryStream).ReadToEnd();

            Assert.Contains("Accepted", responseString);
        }
        public void WriteResponseAsync_WritesOperation()
        {
            OperationResponseItem responseItem    = new OperationResponseItem(new HttpResponseMessage(HttpStatusCode.Accepted));
            MemoryStream          memoryStream    = new MemoryStream();
            IODataResponseMessage responseMessage = new ODataMessageWrapper(memoryStream);
            ODataMessageWriter    writer          = new ODataMessageWriter(responseMessage);
            ODataBatchWriter      batchWriter     = writer.CreateODataBatchWriter();

            batchWriter.WriteStartBatch();

            responseItem.WriteResponseAsync(batchWriter, CancellationToken.None).Wait();

            batchWriter.WriteEndBatch();
            memoryStream.Position = 0;
            string responseString = new StreamReader(memoryStream).ReadToEnd();

            Assert.Contains("Accepted", responseString);
        }
        public string UpdateDataToOData(Change[] changes, string tableName, string[] headers)
        {
            HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, new Uri(this.odataEndpointURL, "$batch"));
            requestMessage.Headers.Add("DataServiceVersion", this.odataVersion);
            requestMessage.Headers.Add("MaxDataServiceVersion", this.odataMaxVersion);
            
            var setting = new ODataMessageWriterSettings();
            setting.SetContentType(ODataFormat.Batch);
            setting.BaseUri = this.odataEndpointURL;

            var odataHttpRequest = new ODataHttpRequest(requestMessage);
            var messageWriter = new ODataMessageWriter(odataHttpRequest, setting, this.metadata);

            var batchWriter = messageWriter.CreateODataBatchWriter();
            batchWriter.WriteStartBatch();
            
            for (int i = 0; i < changes.Length; i++)
            {
                batchWriter.WriteStartChangeset();
                if (changes[i].operation == "DELETE")
                {
                    createDeleteOperationRequestMessage(ref batchWriter, changes[i], tableName);
                }

                if (changes[i].operation == "UPDATE")
                {
                    createUpdateOperationRequestMessage(ref batchWriter, changes[i], tableName, headers);
                }
                batchWriter.WriteEndChangeset();
            }
            
            batchWriter.WriteEndBatch();
            batchWriter.Flush();
            odataHttpRequest.GetStream().Seek(0, SeekOrigin.Begin);

            HttpResponseMessage result = new HttpResponseMessage();

            using (HttpClient client = new HttpClient())
            {
                result = client.SendAsync(requestMessage).Result;
            }

            return parseResponseMessage(result);
        }
        public async Task WriteResponseAsync_SynchronouslyWritesOperation()
        {
            OperationResponseItem responseItem    = new OperationResponseItem(new HttpResponseMessage(HttpStatusCode.Accepted));
            MemoryStream          memoryStream    = new MemoryStream();
            IODataResponseMessage responseMessage = new ODataMessageWrapper(memoryStream);
            ODataMessageWriter    writer          = new ODataMessageWriter(responseMessage);
            ODataBatchWriter      batchWriter     = writer.CreateODataBatchWriter();

            batchWriter.WriteStartBatch();

            // For backward compatibility, default is to write to use a synchronous batchWriter.
            await responseItem.WriteResponseAsync(batchWriter, CancellationToken.None);

            batchWriter.WriteEndBatch();
            memoryStream.Position = 0;
            string responseString = new StreamReader(memoryStream).ReadToEnd();

            Assert.Contains("Accepted", responseString);
        }
Example #21
0
        public void WriteResponseAsync_SynchronouslyWritesOperation_Throws()
        {
            // Arrange
            HttpContext context = HttpContextHelper.Create(StatusCodes.Status202Accepted);

            OperationResponseItem responseItem    = new OperationResponseItem(context);
            MemoryStream          memoryStream    = new MemoryStream();
            IODataResponseMessage responseMessage = new ODataMessageWrapper(memoryStream);
            ODataMessageWriter    writer          = new ODataMessageWriter(responseMessage);

            // Act
            ODataBatchWriter batchWriter = writer.CreateODataBatchWriter();

            batchWriter.WriteStartBatch();

            // Assert
            Action         test      = () => responseItem.WriteResponseAsync(batchWriter).Wait();
            ODataException exception = ExceptionAssert.Throws <ODataException>(test);

            Assert.Equal("An asynchronous operation was called on a synchronous batch writer. Calls on a batch writer instance must be either all synchronous or all asynchronous.",
                         exception.Message);
        }
        public void BatchJsonLightAtomicGroupCannotCreateGroupIdWithNullValue()
        {
            MemoryStream stream = new MemoryStream();

            IODataRequestMessage requestMessage = new InMemoryMessage {
                Stream = stream
            };

            requestMessage.SetHeader("Content-Type", batchContentTypeApplicationJson);
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings();

            settings.BaseUri = new Uri(serviceDocumentUri);

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage, settings))
            {
                ODataBatchWriter batchWriter = messageWriter.CreateODataBatchWriter();
                batchWriter.WriteStartBatch();

                ArgumentNullException ane = Assert.Throws <ArgumentNullException>(() => batchWriter.WriteStartChangeset(null));
                Assert.True(ane.Message.Contains("changesetId"));
            }
        }
        public void WriteResponseAsync_WritesChangeSet()
        {
            HttpResponseMessage[] responses = new HttpResponseMessage[]
                {
                    new HttpResponseMessage(HttpStatusCode.Accepted),
                    new HttpResponseMessage(HttpStatusCode.NoContent)
                };
            ChangeSetResponseItem responseItem = new ChangeSetResponseItem(responses);
            MemoryStream memoryStream = new MemoryStream();
            IODataResponseMessage responseMessage = new ODataMessageWrapper(memoryStream);
            ODataMessageWriter writer = new ODataMessageWriter(responseMessage);
            ODataBatchWriter batchWriter = writer.CreateODataBatchWriter();
            batchWriter.WriteStartBatch();

            responseItem.WriteResponseAsync(batchWriter, CancellationToken.None).Wait();

            batchWriter.WriteEndBatch();
            memoryStream.Position = 0;
            string responseString = new StreamReader(memoryStream).ReadToEnd();

            Assert.Contains("changesetresponse", responseString);
            Assert.Contains("Accepted", responseString);
            Assert.Contains("No Content", responseString);
        }
Example #24
0
        private byte[] ServiceReadRequestAndWriterResponseForMultipartBatchVerifyDependsOnIds(string requestPayload, ODataVersion maxVersion)
        {
            byte[] responseBytes = null;

            IODataRequestMessage requestMessage = new InMemoryMessage()
            {
                Stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(requestPayload))
            };

            requestMessage.SetHeader("Content-Type", batchContentTypeMultipartMime);
            ODataMessageReaderSettings settings = new ODataMessageReaderSettings {
                Version = maxVersion
            };

            using (ODataMessageReader messageReader = new ODataMessageReader(requestMessage, settings, this.userModel))
            {
                MemoryStream responseStream = new MemoryStream();

                IODataResponseMessage responseMessage = new InMemoryMessage {
                    Stream = responseStream
                };

                // Client is expected to receive the response message in the same format as that is used in the request sent.
                responseMessage.SetHeader("Content-Type", batchContentTypeMultipartMime);
                using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage))
                {
                    ODataBatchWriter batchWriter = messageWriter.CreateODataBatchWriter();
                    batchWriter.WriteStartBatch();

                    ODataBatchReader batchReader = messageReader.CreateODataBatchReader();
                    while (batchReader.Read())
                    {
                        switch (batchReader.State)
                        {
                        case ODataBatchReaderState.Operation:
                            // Encountered an operation (either top-level or in a change set)
                            ODataBatchOperationRequestMessage operationMessage =
                                batchReader.CreateOperationRequestMessage();

                            // Verify DependsOnIds are set correctly
                            IEnumerable <string> dependsOnIds = operationMessage.DependsOnIds;
                            switch (operationMessage.ContentId)
                            {
                            case "1":
                            case "2A":
                                Assert.True(dependsOnIds.Count() == 0);
                                break;

                            case "2B":
                                Assert.True(dependsOnIds.SequenceEqual(new List <string> {
                                    "2A"
                                }));
                                break;

                            case "2C":
                                Assert.True(dependsOnIds.SequenceEqual(new List <string> {
                                    "2A", "2B"
                                }));
                                break;

                            case "3":
                                Assert.True(dependsOnIds.SequenceEqual(new List <string> {
                                    "1"
                                }));
                                break;

                            default:
                                break;
                            }

                            ODataBatchOperationResponseMessage response =
                                batchWriter.CreateOperationResponseMessage(operationMessage.ContentId);
                            if (operationMessage.Method == "PATCH")
                            {
                                response.StatusCode = 204;
                                response.SetHeader("Content-Type", "application/json;odata.metadata=none");
                            }
                            else if (operationMessage.Method == "PUT")
                            {
                                response.StatusCode = 201;
                                response.SetHeader("Content-Type", "application/json;");
                            }

                            break;

                        case ODataBatchReaderState.ChangesetStart:
                            batchWriter.WriteStartChangeset();
                            break;

                        case ODataBatchReaderState.ChangesetEnd:
                            batchWriter.WriteEndChangeset();
                            break;
                        }
                    }

                    batchWriter.WriteEndBatch();

                    responseStream.Position = 0;
                    responseBytes           = responseStream.ToArray();
                }

                return(responseBytes);
            }
        }
Example #25
0
        internal static Tuple <HttpWebRequest, Stream> BuildRequestForTableBatchOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int?timeout, string tableName, TableBatchOperation batch, bool useVersionHeader, OperationContext ctx, TableRequestOptions options, string accountName)
        {
            HttpWebRequest     msg           = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), builder, "POST", timeout, useVersionHeader, ctx);
            TablePayloadFormat payloadFormat = options.PayloadFormat.Value;

            Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat);

            // create the writer, indent for readability of the examples.
            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
            {
                CheckCharacters = false,                              // sets this flag on the XmlWriter for ATOM
                Version         = TableConstants.ODataProtocolVersion // set the Odata version to use when writing the entry
            };

            HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg, bufferManager);

            // Start Batch
            ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings);
            ODataBatchWriter   batchWriter = odataWriter.CreateODataBatchWriter();

            batchWriter.WriteStartBatch();

            bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve;

            // Query operations should not be inside changeset in payload
            if (!isQuery)
            {
                // Start Operation
                batchWriter.WriteStartChangeset();
                batchWriter.Flush();
            }

            foreach (TableOperation operation in batch)
            {
                string httpMethod = operation.HttpMethod;
                if (operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge)
                {
                    options.AssertNoEncryptionPolicyOrStrictMode();
                    httpMethod = "MERGE";
                }

                ODataBatchOperationRequestMessage mimePartMsg = batchWriter.CreateOperationRequestMessage(httpMethod, operation.GenerateRequestURI(uri, tableName));
                SetAcceptAndContentTypeForODataBatchMessage(mimePartMsg, payloadFormat);

                // etag
                if (operation.OperationType == TableOperationType.Delete ||
                    operation.OperationType == TableOperationType.Replace ||
                    operation.OperationType == TableOperationType.Merge)
                {
                    mimePartMsg.SetHeader("If-Match", operation.Entity.ETag);
                }

                // Prefer header
                if (operation.OperationType == TableOperationType.Insert)
                {
                    mimePartMsg.SetHeader("Prefer", operation.EchoContent ? "return-content" : "return-no-content");
                }

                if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve)
                {
                    using (ODataMessageWriter batchEntryWriter = new ODataMessageWriter(mimePartMsg, writerSettings, new TableStorageModel(accountName)))
                    {
                        // Write entity
                        ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter();
                        WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter, options);
                    }
                }
            }

            if (!isQuery)
            {
                // End Operation
                batchWriter.WriteEndChangeset();
            }

            // End Batch
            batchWriter.WriteEndBatch();
            batchWriter.Flush();

            return(new Tuple <HttpWebRequest, Stream>(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream()));
        }
Example #26
0
        protected void Button4_Click(object sender, EventArgs e)
        {
            string accessToken = ((Button)sender).CommandArgument;
            Int16 operationCount = 0;

            if (IsPostBack)
            {
                // Get the host web's URL.
                sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);
            }

            // Create the parent request
            var batchRequest = new BatchODataRequest(String.Format("{0}/_api/", sharepointUrl)); // ctor adds "$batch"
            batchRequest.SetHeader("Authorization", "Bearer " + accessToken);

            using (var oDataMessageWriter = new ODataMessageWriter(batchRequest))
            {
                var oDataBatchWriter = oDataMessageWriter.CreateODataBatchWriter();
                oDataBatchWriter.WriteStartBatch();

                oDataBatchWriter.WriteStartChangeset();

                // Create the list deleting operation
                var deleteOperation = oDataBatchWriter.CreateOperationRequestMessage(
                    "DELETE", new Uri(sharepointUrl.ToString() + "/_api/Web/lists/getbytitle(\'" +OldList.Text+ "\')"));
                deleteOperation.SetHeader("If-Match", "\"1\"");

                oDataBatchWriter.WriteEndChangeset();
                operationCount++;

                // Create the query operation
                var queryOperationMessage3 = oDataBatchWriter.CreateOperationRequestMessage(
                    "GET", new Uri(sharepointUrl.ToString() + "/_api/Web/lists"));
                operationCount++;

                oDataBatchWriter.WriteEndBatch();
                oDataBatchWriter.Flush();
            }

            // Parse the response and bind the data to the UI controls
            var oDataResponse = batchRequest.GetResponse();

            using (var oDataReader = new ODataMessageReader(oDataResponse))
            {
                var oDataBatchReader = oDataReader.CreateODataBatchReader();

                while (oDataBatchReader.Read())
                {
                    switch (oDataBatchReader.State)
                    {
                        case ODataBatchReaderState.Initial:
                            // Optionally, handle the start of a batch payload.
                            break;

                        case ODataBatchReaderState.Operation:
                            // Encountered an operation (either top-level or in a changeset)
                            var operationResponse = oDataBatchReader.CreateOperationResponseMessage();

                            // Response ATOM markup parsing and presentation
                            using (var stream = operationResponse.GetStream())
                            {

                                switch (operationCount)
                                {
                                    case 2: // The "delete list" operation

                                        if (operationResponse.StatusCode == 200)
                                        {
                                            DeleteListResponse.Text = "Your list was deleted!";
                                        }
                                        else
                                        {
                                            DeleteListResponse.Text = "Your list was not deleted. Status returned: " + operationResponse.StatusCode.ToString();
                                        }

                                        operationCount--;
                                        break;

                                    case 1: // The "List of Lists" operation

                                        // Bind data to the grid on the page.
                                           // In a production app, check operationResponse.StatusCode and handle non-200 statuses.
                                           // For simplicity, this sample assumes status 200 (the list items are returned).
                                        List<XElement> entries = SharePointDataHelpers.ListDataHelper.ExtractListItemsFromATOMResponse(stream);
                                        var itemTitles = SharePointDataHelpers.ListDataHelper.GetItemTitles(entries);
                                        GridView4.DataSource = itemTitles;
                                        GridView4.DataBind();
                                        operationCount--;
                                        break;
                                }
                            };
                            break;

                        case ODataBatchReaderState.ChangesetStart:
                            // Optionally, handle the start of a change set.
                            break;

                        case ODataBatchReaderState.ChangesetEnd:
                            // When this sample was created, SharePoint did not support "all or nothing" transactions. 
                            // If that changes in the future this is where you would commit the transaction.
                            break;

                        case ODataBatchReaderState.Exception:
                            // In a producition app handle exeception. Omitted for simplicity in this sample app.
                            break;
                    }
                }
            }

            GridView3.Visible = false;
        }
        private byte[] ServiceReadAsyncBatchRequestAndWriteAsyncResponse(byte[] requestPayload)
        {
            IODataRequestMessage requestMessage = new InMemoryMessage()
            {
                Stream = new MemoryStream(requestPayload)
            };

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

            using (var messageReader = new ODataMessageReader(requestMessage, new ODataMessageReaderSettings {
                BaseUri = new Uri(serviceDocumentUri)
            }, this.userModel))
            {
                var responseStream = new MemoryStream();

                IODataResponseMessage responseMessage = new InMemoryMessage {
                    Stream = responseStream
                };
                responseMessage.SetHeader("Content-Type", batchContentType);
                var messageWriter = new ODataMessageWriter(responseMessage);
                var batchWriter   = messageWriter.CreateODataBatchWriter();
                batchWriter.WriteStartBatch();

                var batchReader = messageReader.CreateODataBatchReader();
                while (batchReader.Read())
                {
                    switch (batchReader.State)
                    {
                    case ODataBatchReaderState.Operation:
                        // Encountered an operation (either top-level or in a changeset)
                        var operationMessage = batchReader.CreateOperationRequestMessage();
                        if (operationMessage.Method == "GET" && operationMessage.Url.AbsolutePath.Contains("ALFKI"))
                        {
                            var response = batchWriter.CreateOperationResponseMessage(null);
                            response.StatusCode = 200;
                            response.SetHeader("Content-Type", "application/json;");
                            var settings = new ODataMessageWriterSettings();
                            settings.SetServiceDocumentUri(new Uri(serviceDocumentUri));
                            using (var operationMessageWriter = new ODataMessageWriter(response, settings, this.userModel))
                            {
                                var entryWriter = operationMessageWriter.CreateODataResourceWriter(this.customers, this.customerType);
                                var entry       = new ODataResource()
                                {
                                    TypeName = "MyNS.Customer", Properties = new[] { new ODataProperty()
                                                                                     {
                                                                                         Name = "Id", Value = "ALFKI"
                                                                                     }, new ODataProperty()
                                                                                     {
                                                                                         Name = "Name", Value = "John"
                                                                                     } }
                                };
                                entryWriter.WriteStart(entry);
                                entryWriter.WriteEnd();
                            }
                        }
                        break;
                    }
                }

                var asyncResponse = batchWriter.CreateOperationResponseMessage(null);
                asyncResponse.StatusCode = 202;
                asyncResponse.SetHeader("Location", "http://service/async-monitor");
                asyncResponse.SetHeader("Retry-After", "10");

                batchWriter.WriteEndBatch();

                responseStream.Position = 0;
                return(responseStream.ToArray());
            }
        }
        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());
            }
        }
        internal static Tuple<HttpWebRequest, Stream> BuildRequestForTableBatchOperation(Uri uri, UriQueryBuilder builder, IBufferManager bufferManager, int? timeout, string tableName, TableBatchOperation batch, bool useVersionHeader, OperationContext ctx, TableRequestOptions options, string accountName)
        {
            HttpWebRequest msg = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), builder, "POST", timeout, useVersionHeader, ctx);
            TablePayloadFormat payloadFormat = options.PayloadFormat.Value;
            Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat);

            // create the writer, indent for readability of the examples.  
            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
            {
                CheckCharacters = false,   // sets this flag on the XmlWriter for ATOM  
                Version = TableConstants.ODataProtocolVersion // set the Odata version to use when writing the entry 
            };

            HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg, bufferManager);

            ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings);

            ODataBatchWriter batchWriter = odataWriter.CreateODataBatchWriter();
            batchWriter.WriteStartBatch();

            bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve;

            // Query operations should not be inside changeset in payload
            if (!isQuery)
            {
                // Start Operation
                batchWriter.WriteStartChangeset();
                batchWriter.Flush();
            }

            foreach (TableOperation operation in batch)
            {
                string httpMethod = operation.HttpMethod;
                if (operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge)
                {
                    options.AssertNoEncryptionPolicyOrStrictMode();
                    httpMethod = "MERGE";
                }

                ODataBatchOperationRequestMessage mimePartMsg = batchWriter.CreateOperationRequestMessage(httpMethod, operation.GenerateRequestURI(uri, tableName));
                SetAcceptAndContentTypeForODataBatchMessage(mimePartMsg, payloadFormat);

                // etag
                if (operation.OperationType == TableOperationType.Delete ||
                    operation.OperationType == TableOperationType.Replace ||
                    operation.OperationType == TableOperationType.Merge)
                {
                    mimePartMsg.SetHeader("If-Match", operation.Entity.ETag);
                }

                // Prefer header
                if (operation.OperationType == TableOperationType.Insert)
                {
                    mimePartMsg.SetHeader("Prefer", operation.EchoContent ? "return-content" : "return-no-content");
                }
                
                if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve)
                {
                    using (ODataMessageWriter batchEntryWriter = new ODataMessageWriter(mimePartMsg, writerSettings, new TableStorageModel(accountName)))
                    {
                        // Write entity
                        ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter();
                        WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter, options);
                    }
                }
            }

            if (!isQuery)
            {
                // End Operation
                batchWriter.WriteEndChangeset();
            }

            // End Batch
            batchWriter.WriteEndBatch();
            batchWriter.Flush();

            return new Tuple<HttpWebRequest, Stream>(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream());
        }
        private byte[] ServiceReadBatchRequestAndWriterBatchResponse(byte[] requestPayload, BodyContentType bodyContentType)
        {
            IODataRequestMessage requestMessage = new InMemoryMessage()
            {
                Stream = new MemoryStream(requestPayload)
            };

            requestMessage.SetHeader(ODataConstants.ContentTypeHeader, batchContentTypeApplicationJson);

            using (ODataMessageReader messageReader = new ODataMessageReader(requestMessage, new ODataMessageReaderSettings(), null))
            {
                MemoryStream responseStream = new MemoryStream();

                IODataResponseMessage responseMessage = new InMemoryMessage {
                    Stream = responseStream
                };

                // Client is expected to receive the response message in the same format as that is used in the request sent.
                responseMessage.SetHeader(ODataConstants.ContentTypeHeader, batchContentTypeApplicationJson);
                ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage);
                ODataBatchWriter   batchWriter   = messageWriter.CreateODataBatchWriter();
                batchWriter.WriteStartBatch();

                ODataBatchReader batchReader = messageReader.CreateODataBatchReader();
                while (batchReader.Read())
                {
                    switch (batchReader.State)
                    {
                    case ODataBatchReaderState.Operation:

                        ODataBatchOperationRequestMessage operationMessage = batchReader.CreateOperationRequestMessage();

                        if (operationMessage.Method == "PUT")
                        {
                            using (Stream operationMessageBodyStream = operationMessage.GetStream())
                            {
                                // Verify the bytes in the request operation stream.
                                byte[] sampleBytes = bodyContentType == BodyContentType.Textual
                                        ? Encoding.UTF8.GetBytes("\"" + this.textualSampleStringA + "\"")
                                        : binarySampleBytesA;
                                Assert.Equal(operationMessageBodyStream.Length, sampleBytes.Length);
                                foreach (byte samplebyte in sampleBytes)
                                {
                                    Assert.Equal(samplebyte, operationMessageBodyStream.ReadByte());
                                }
                            }

                            // Create the response.
                            ODataBatchOperationResponseMessage operationResponse = batchWriter.CreateOperationResponseMessage(operationMessage.ContentId);
                            operationResponse.StatusCode = 201;
                            operationResponse.SetHeader("CoNtEnT-TyPe", "application/json;odata.metadata=none");
                        }
                        else if (operationMessage.Method == "GET")
                        {
                            ODataBatchOperationResponseMessage operationResponse = batchWriter.CreateOperationResponseMessage(operationMessage.ContentId);
                            operationResponse.StatusCode = 200;
                            operationResponse.SetHeader("CoNtEnT-TyPe", GetContentType(bodyContentType));
                            ODataMessageWriterSettings settings = new ODataMessageWriterSettings();
                            settings.SetServiceDocumentUri(new Uri(serviceDocumentUri));
                            using (ODataMessageWriter operationMessageWriter = new ODataMessageWriter(operationResponse, settings, null))
                            {
                                operationMessageWriter.WriteValue(GetEncodedContentObject(bodyContentType, false));
                            }
                        }

                        break;

                    case ODataBatchReaderState.ChangesetStart:
                        batchWriter.WriteStartChangeset();
                        break;

                    case ODataBatchReaderState.ChangesetEnd:
                        batchWriter.WriteEndChangeset();
                        break;
                    }
                }

                batchWriter.WriteEndBatch();
                responseStream.Position = 0;
                return(responseStream.ToArray());
            }
        }
        private byte[] ServiceReadAsyncBatchRequestAndWriteAsyncResponse(byte[] requestPayload)
        {
            IODataRequestMessage requestMessage = new InMemoryMessage() { Stream = new MemoryStream(requestPayload) };
            requestMessage.SetHeader("Content-Type", batchContentType);

            using (var messageReader = new ODataMessageReader(requestMessage, new ODataMessageReaderSettings(), this.userModel))
            {
                var responseStream = new MemoryStream();

                IODataResponseMessage responseMessage = new InMemoryMessage { Stream = responseStream };
                responseMessage.SetHeader("Content-Type", batchContentType);
                var messageWriter = new ODataMessageWriter(responseMessage);
                var batchWriter = messageWriter.CreateODataBatchWriter();
                batchWriter.WriteStartBatch();

                var batchReader = messageReader.CreateODataBatchReader();
                while (batchReader.Read())
                {
                    switch (batchReader.State)
                    {
                        case ODataBatchReaderState.Operation:
                            // Encountered an operation (either top-level or in a changeset)
                            var operationMessage = batchReader.CreateOperationRequestMessage();
                            if (operationMessage.Method == "GET" && operationMessage.Url.AbsolutePath.Contains("ALFKI"))
                            {
                                var response = batchWriter.CreateOperationResponseMessage(null);
                                response.StatusCode = 200;
                                response.SetHeader("Content-Type", "application/json;");
                                var settings = new ODataMessageWriterSettings();
                                settings.SetServiceDocumentUri(new Uri(serviceDocumentUri));
                                using (var operationMessageWriter = new ODataMessageWriter(response, settings, this.userModel))
                                {
                                    var entryWriter = operationMessageWriter.CreateODataEntryWriter(this.customers, this.customerType);
                                    var entry = new ODataEntry() { TypeName = "MyNS.Customer", Properties = new[] { new ODataProperty() { Name = "Id", Value = "ALFKI" }, new ODataProperty() { Name = "Name", Value = "John" } } };
                                    entryWriter.WriteStart(entry);
                                    entryWriter.WriteEnd();
                                }
                            }
                            break;
                    }
                }

                var asyncResponse = batchWriter.CreateOperationResponseMessage(null);
                asyncResponse.StatusCode = 202;
                asyncResponse.SetHeader("Location", "http://service/async-monitor");
                asyncResponse.SetHeader("Retry-After", "10");

                batchWriter.WriteEndBatch();

                responseStream.Position = 0;
                return responseStream.ToArray();
            }
        }
        protected void Button2_Click(object sender, EventArgs e)
        {
            string accessToken        = ((Button)sender).CommandArgument;
            Int16  listRetrievalCount = 0;

            if (IsPostBack)
            {
                // Get the host web's URL.
                sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);
            }

            // Create the parent request
            var batchRequest = new BatchODataRequest(sharepointUrl + "_api/"); // ctor adds "$batch"

            batchRequest.SetHeader("Authorization", "Bearer " + accessToken);

            using (var oDataMessageWriter = new ODataMessageWriter(batchRequest))
            {
                var oDataBatchWriter = oDataMessageWriter.CreateODataBatchWriter();
                oDataBatchWriter.WriteStartBatch();

                // Create the two child query operations.
                oDataBatchWriter.CreateOperationRequestMessage(
                    "GET", new Uri(sharepointUrl.ToString() + "_api/Web/lists/getbytitle('Composed Looks')/items?$select=Title"));
                listRetrievalCount++;

                oDataBatchWriter.CreateOperationRequestMessage(
                    "GET", new Uri(sharepointUrl.ToString() + "_api/Web/lists/getbytitle('User Information List')/items?$select=Title"));
                listRetrievalCount++;

                oDataBatchWriter.WriteEndBatch();
                oDataBatchWriter.Flush();
            }

            // Parse the response and bind the data to the UI controls
            var oDataResponse = batchRequest.GetResponse();

            using (var oDataReader = new ODataMessageReader(oDataResponse))
            {
                var oDataBatchReader = oDataReader.CreateODataBatchReader();

                while (oDataBatchReader.Read())
                {
                    switch (oDataBatchReader.State)
                    {
                    case ODataBatchReaderState.Initial:

                        // Optionally, handle the start of a batch payload.
                        break;

                    case ODataBatchReaderState.Operation:

                        // Start of an operation (either top-level or in a changeset)
                        var operationResponse = oDataBatchReader.CreateOperationResponseMessage();

                        // Response's ATOM markup parsing and presentation section
                        using (var stream = operationResponse.GetStream())
                        {
                            List <XElement> entries = SharePointDataHelpers.ListDataHelper.ExtractListItemsFromATOMResponse(stream);

                            var itemTitles = SharePointDataHelpers.ListDataHelper.GetItemTitles(entries);

                            // Bind data to the grid on the page.
                            // In a production app, check operationResponse.StatusCode and handle non-200 statuses.
                            // For simplicity, this sample assumes status 200 (the list items are returned).
                            switch (listRetrievalCount)
                            {
                            case 2:
                                GridView2.DataSource = itemTitles;
                                GridView2.DataBind();
                                listRetrievalCount--;
                                break;

                            case 1:
                                GridView1.DataSource = itemTitles;
                                GridView1.DataBind();
                                listRetrievalCount--;
                                break;
                            }
                        };
                        break;

                    case ODataBatchReaderState.ChangesetStart:
                        // Optionally, handle the start of a change set.
                        break;

                    case ODataBatchReaderState.ChangesetEnd:
                        // When this sample was created, SharePoint did not support "all or nothing" transactions.
                        // If that changes in the future this is where you would commit the transaction.
                        break;

                    case ODataBatchReaderState.Exception:
                        // In a producition app handle exeception. Omitted for simplicity in this sample app.
                        break;
                    }
                }
            }
            TwoLists.Visible = true;
        }
        private byte[] ServiceReadReferenceUriBatchRequestAndWriteResponse(byte[] requestPayload)
        {
            IODataRequestMessage requestMessage = new InMemoryMessage()
            {
                Stream = new MemoryStream(requestPayload)
            };

            requestMessage.SetHeader("Content-Type", batchContentTypeApplicationJson);
            ODataMessageReaderSettings settings = new ODataMessageReaderSettings();

            settings.BaseUri = new Uri(serviceDocumentUri);

            byte[] responseBytes = null;

            using (ODataMessageReader messageReader = new ODataMessageReader(requestMessage, settings, this.userModel))
            {
                MemoryStream responseStream = new MemoryStream();

                IODataResponseMessage responseMessage = new InMemoryMessage {
                    Stream = responseStream
                };

                // Client is expected to receive the response message in the same format as that is used in the request sent.
                responseMessage.SetHeader("Content-Type", batchContentTypeApplicationJson);

                using (ODataMessageWriter messageWriter = new ODataMessageWriter(responseMessage))
                {
                    ODataBatchWriter batchWriter = messageWriter.CreateODataBatchWriter();
                    batchWriter.WriteStartBatch();

                    ODataBatchReader batchReader = messageReader.CreateODataBatchReader();
                    while (batchReader.Read())
                    {
                        switch (batchReader.State)
                        {
                        case ODataBatchReaderState.Operation:
                            // Encountered an operation (either top-level or in a change set)
                            ODataBatchOperationRequestMessage operationMessage =
                                batchReader.CreateOperationRequestMessage();

                            ODataBatchOperationResponseMessage response =
                                batchWriter.CreateOperationResponseMessage(operationMessage.ContentId);

                            if (operationMessage.Method == "PUT")
                            {
                                using (ODataMessageReader operationMessageReader = new ODataMessageReader(
                                           operationMessage, new ODataMessageReaderSettings(), this.userModel))
                                {
                                    ODataReader reader = operationMessageReader.CreateODataResourceReader();
                                    Assert.NotNull(reader);
                                }

                                response.StatusCode = 201;
                                response.SetHeader("Content-Type", "application/json;odata.metadata=none");
                            }
                            else if (operationMessage.Method == "PATCH")
                            {
                                using (ODataMessageReader operationMessageReader = new ODataMessageReader(
                                           operationMessage, new ODataMessageReaderSettings(), this.userModel))
                                {
                                    ODataReader reader = operationMessageReader.CreateODataResourceReader();
                                    Assert.NotNull(reader);
                                }

                                response.StatusCode = 204;
                            }
                            else if (operationMessage.Method == "GET")
                            {
                                response.StatusCode = 200;
                                response.SetHeader("Content-Type", "application/json;");
                                ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings();
                                writerSettings.ODataUri.ServiceRoot = new Uri(serviceDocumentUri);
                                using (
                                    ODataMessageWriter operationMessageWriter = new ODataMessageWriter(response,
                                                                                                       writerSettings, this.userModel))
                                {
                                    ODataWriter entryWriter =
                                        operationMessageWriter.CreateODataResourceWriter(this.singleton,
                                                                                         this.webType);
                                    ODataResource entry = new ODataResource()
                                    {
                                        TypeName   = "NS.Web",
                                        Properties = new[]
                                        {
                                            new ODataProperty()
                                            {
                                                Name = "WebId", Value = -1
                                            },
                                            new ODataProperty()
                                            {
                                                Name = "Name", Value = aVeryLongString
                                            }
                                        }
                                    };
                                    entryWriter.WriteStart(entry);
                                    entryWriter.WriteEnd();
                                }
                            }

                            break;

                        case ODataBatchReaderState.ChangesetStart:
                            // Set the group Id on the writer side to correlate with request.
                            string atomicGroupId = batchReader.CurrentGroupId;
                            batchWriter.WriteStartChangeset(atomicGroupId);
                            break;

                        case ODataBatchReaderState.ChangesetEnd:
                            batchWriter.WriteEndChangeset();
                            break;
                        }
                    }

                    batchWriter.WriteEndBatch();

                    responseStream.Position = 0;
                    responseBytes           = responseStream.ToArray();
                }

                return(responseBytes);
            }
        }
        internal static StorageRequestMessage BuildRequestForTableBatchOperation <T>(RESTCommand <T> cmd, Uri uri, UriQueryBuilder builder, int?timeout, string tableName, TableBatchOperation batch, CloudTableClient client, HttpContent content, OperationContext ctx, TablePayloadFormat payloadFormat, ICanonicalizer canonicalizer, StorageCredentials credentials)
        {
            StorageRequestMessage msg = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), builder, HttpMethod.Post, timeout, content, ctx, canonicalizer, credentials);

            Logger.LogInformational(ctx, SR.PayloadFormat, payloadFormat);

            // create the writer, indent for readability of the examples.
            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
            {
                CheckCharacters = false,                              // sets this flag on the XmlWriter for ATOM
                Version         = TableConstants.ODataProtocolVersion // set the Odata version to use when writing the entry
            };

            HttpRequestAdapterMessage adapterMsg = new HttpRequestAdapterMessage(msg, client.BufferManager, 64 * (int)Constants.KB);

            cmd.StreamToDispose = adapterMsg.GetStream();

            // Start Batch
            ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings);
            ODataBatchWriter   batchWriter = odataWriter.CreateODataBatchWriter();

            batchWriter.WriteStartBatch();

            bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve;

            // Query operations should not be inside changeset in payload
            if (!isQuery)
            {
                // Start Operation
                batchWriter.WriteStartChangeset();
                batchWriter.Flush();
            }

            foreach (TableOperation operation in batch)
            {
                string httpMethod = operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge ? "MERGE" : operation.HttpMethod.Method;

                ODataBatchOperationRequestMessage mimePartMsg = batchWriter.CreateOperationRequestMessage(httpMethod, operation.GenerateRequestURI(uri, tableName));
                SetAcceptAndContentTypeForODataBatchMessage(mimePartMsg, payloadFormat);

                // etag
                if (operation.OperationType == TableOperationType.Delete ||
                    operation.OperationType == TableOperationType.Replace ||
                    operation.OperationType == TableOperationType.Merge)
                {
                    mimePartMsg.SetHeader("If-Match", operation.Entity.ETag);
                }

                // Prefer header
                if (operation.OperationType == TableOperationType.Insert)
                {
                    mimePartMsg.SetHeader("Prefer", operation.EchoContent ? "return-content" : "return-no-content");
                }

                if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve)
                {
                    using (ODataMessageWriter batchEntryWriter = new ODataMessageWriter(mimePartMsg, writerSettings, new TableStorageModel(client.AccountName)))
                    {
                        // Write entity
                        ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter();
                        WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter);
                    }
                }
            }

            if (!isQuery)
            {
                // End Operation
                batchWriter.WriteEndChangeset();
            }

            // End Batch
            batchWriter.WriteEndBatch();
            batchWriter.Flush();

            return(adapterMsg.GetPopulatedMessage());
        }
        private byte[] CreateBigBatchRequest(int repeatCount)
        {
            MemoryStream stream = new MemoryStream();

            IODataRequestMessage requestMessage = new InMemoryMessage {
                Stream = stream
            };

            requestMessage.SetHeader("Content-Type", batchContentTypeApplicationJson);
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings();

            settings.BaseUri = new Uri(serviceDocumentUri);

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage, settings))
            {
                ODataBatchWriter batchWriter = messageWriter.CreateODataBatchWriter();
                batchWriter.WriteStartBatch();

                // Each iteration generates a change set with two operations, followed by one top level operation.
                // Operations count in each iteration is three.
                for (int idx = 0; idx < repeatCount * 3; idx += 3)
                {
                    batchWriter.WriteStartChangeset();

                    ODataBatchOperationRequestMessage createOperationMessage = batchWriter.CreateOperationRequestMessage(
                        "PUT",
                        new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/{1}", serviceDocumentUri, "MySingleton")),
                        idx.ToString());

                    using (ODataMessageWriter operationMessageWriter = new ODataMessageWriter(createOperationMessage))
                    {
                        ODataWriter   entryWriter = operationMessageWriter.CreateODataResourceWriter();
                        ODataResource entry       = new ODataResource()
                        {
                            TypeName   = "NS.Web",
                            Properties = new[]
                            {
                                new ODataProperty()
                                {
                                    Name = "WebId", Value = "webid_" + idx
                                },
                                new ODataProperty()
                                {
                                    Name = "Name", Value = this.aVeryLongString
                                }
                            }
                        };
                        entryWriter.WriteStart(entry);
                        entryWriter.WriteEnd();
                    }

                    // A PATCH operation that depends on the preceding PUT operation.
                    List <string> dependsOnIds = new List <string> {
                        idx.ToString()
                    };

                    ODataBatchOperationRequestMessage updateOperationMessage = batchWriter.CreateOperationRequestMessage(
                        "PATCH",
                        new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/{1}", serviceDocumentUri, "$" + idx)),
                        (idx + 1).ToString(),
                        BatchPayloadUriOption.AbsoluteUri,
                        dependsOnIds);

                    // Verify that input values are copied into a new list.
                    Assert.Equal(dependsOnIds, updateOperationMessage.DependsOnIds);
                    Assert.NotSame(dependsOnIds, updateOperationMessage.DependsOnIds);

                    using (ODataMessageWriter operationMessageWriter = new ODataMessageWriter(updateOperationMessage))
                    {
                        var entryWriter = operationMessageWriter.CreateODataResourceWriter();
                        var entry       = new ODataResource()
                        {
                            TypeName   = "NS.Web",
                            Properties = new[] { new ODataProperty()
                                                 {
                                                     Name = "WebId", Value = "webid_" + (idx + 1)
                                                 } }
                        };
                        entryWriter.WriteStart(entry);
                        entryWriter.WriteEnd();
                    }

                    Assert.Equal(createOperationMessage.GroupId, updateOperationMessage.GroupId);
                    batchWriter.WriteEndChangeset();

                    ODataBatchOperationRequestMessage queryOperationMessage = batchWriter.CreateOperationRequestMessage(
                        "GET",
                        new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/{1}", serviceDocumentUri, "MySingleton")),
                        (idx + 2).ToString());
                    queryOperationMessage.SetHeader("Accept", "application/json;odata.metadata=full");
                }

                batchWriter.WriteEndBatch();

                stream.Position = 0;
                return(stream.ToArray());
            }
        }
        /// <summary>
        /// Create a batch request that contains one atomic groups.
        /// </summary>
        /// <param name="atomicGroupIdFromRequest">Output string for the atomic group id from the batch created.</param>
        /// <returns>Stream containing the batch request.</returns>
        private byte[] CreateBatchRequestWithAtomicGroup(out string atomicGroupIdFromRequest)
        {
            MemoryStream stream = new MemoryStream();

            IODataRequestMessage requestMessage = new InMemoryMessage {
                Stream = stream
            };

            requestMessage.SetHeader("Content-Type", batchContentTypeApplicationJson);
            ODataMessageWriterSettings settings = new ODataMessageWriterSettings();

            settings.BaseUri = new Uri(serviceDocumentUri);

            using (ODataMessageWriter messageWriter = new ODataMessageWriter(requestMessage, settings))
            {
                ODataBatchWriter batchWriter = messageWriter.CreateODataBatchWriter();
                batchWriter.WriteStartBatch();

                batchWriter.WriteStartChangeset();

                // Create operation.
                ODataBatchOperationRequestMessage createOperationMessage = batchWriter.CreateOperationRequestMessage(
                    "PUT",
                    new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/{1}", serviceDocumentUri, "MySingleton")),
                    "1");

                using (ODataMessageWriter operationMessageWriter = new ODataMessageWriter(createOperationMessage))
                {
                    ODataWriter   entryWriter = operationMessageWriter.CreateODataResourceWriter();
                    ODataResource entry       = new ODataResource()
                    {
                        TypeName   = "NS.Web",
                        Properties = new[]
                        {
                            new ODataProperty()
                            {
                                Name = "WebId", Value = 10
                            },
                            new ODataProperty()
                            {
                                Name = "Name", Value = "SingletonWebForBatchJsonLightAtomicGroupIdTest"
                            }
                        }
                    };
                    entryWriter.WriteStart(entry);
                    entryWriter.WriteEnd();
                }

                // A PATCH operation that depends on the preceding PUT operation.
                List <string> dependsOnIds = new List <string> {
                    "1"
                };

                ODataBatchOperationRequestMessage updateOperationMessage = batchWriter.CreateOperationRequestMessage(
                    "PATCH",
                    new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/{1}", serviceDocumentUri, "$1")),
                    "2",
                    BatchPayloadUriOption.AbsoluteUri,
                    dependsOnIds);

                // Verify that input values are copied into a new list.
                Assert.Equal(dependsOnIds, updateOperationMessage.DependsOnIds);
                Assert.NotSame(dependsOnIds, updateOperationMessage.DependsOnIds);

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

                Assert.Equal(createOperationMessage.GroupId, updateOperationMessage.GroupId);
                batchWriter.WriteEndChangeset();

                ODataBatchOperationRequestMessage update2OperationMessage = batchWriter.CreateOperationRequestMessage(
                    "PATCH",
                    new Uri(string.Format(CultureInfo.InvariantCulture, "{0}/{1}", serviceDocumentUri, "MySingleton")),
                    "3",
                    BatchPayloadUriOption.AbsoluteUri);

                using (ODataMessageWriter operationMessageWriter = new ODataMessageWriter(update2OperationMessage))
                {
                    var entryWriter = operationMessageWriter.CreateODataResourceWriter();
                    var entry       = new ODataResource()
                    {
                        TypeName   = "NS.Web",
                        Properties = new[] { new ODataProperty()
                                             {
                                                 Name = "WebId", Value = 12
                                             } }
                    };
                    entryWriter.WriteStart(entry);
                    entryWriter.WriteEnd();
                }
                batchWriter.WriteEndBatch();
                atomicGroupIdFromRequest = createOperationMessage.GroupId;

                stream.Position = 0;
                return(stream.ToArray());
            }
        }
        protected void Button3_Click(object sender, EventArgs e)
        {
            string accessToken    = ((Button)sender).CommandArgument;
            Int16  operationCount = 0;

            if (IsPostBack)
            {
                // Get the host web's URL.
                sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);
            }

            // Create the parent request
            var batchRequest = new BatchODataRequest(sharepointUrl + "_api/"); // ctor adds "$batch"

            batchRequest.SetHeader("Authorization", "Bearer " + accessToken);

            using (var oDataMessageWriter = new ODataMessageWriter(batchRequest))
            {
                var oDataBatchWriter = oDataMessageWriter.CreateODataBatchWriter();
                oDataBatchWriter.WriteStartBatch();

                oDataBatchWriter.WriteStartChangeset();

                // Create the list adding operation
                var addListOperation = oDataBatchWriter.CreateOperationRequestMessage(
                    "POST", new Uri(sharepointUrl.ToString() + "_api/lists"));
                addListOperation.SetHeader("Content-Type", "application/json;odata=verbose");

                // Write the body of the operation
                using (var oDataInsertWriter = new ODataMessageWriter(addListOperation))
                {
                    var entryWriter = oDataInsertWriter.CreateODataEntryWriter();

                    var insertionBody = new ODataEntry()
                    {
                        Properties = new[]
                        {
                            new ODataProperty()
                            {
                                Name = "Title", Value = NewList.Text
                            },
                            new ODataProperty()
                            {
                                Name = "BaseTemplate", Value = "100"
                            }
                        }
                    };

                    // Set the "__metadata" type property
                    insertionBody.TypeName = "SP.List";

                    entryWriter.WriteStart(insertionBody);
                    entryWriter.WriteEnd();
                }
                oDataBatchWriter.WriteEndChangeset();
                operationCount++;

                // Create the query operation
                var queryOperationMessage3 = oDataBatchWriter.CreateOperationRequestMessage(
                    "GET", new Uri(sharepointUrl.ToString() + "_api/Web/lists"));
                operationCount++;

                oDataBatchWriter.WriteEndBatch();
                oDataBatchWriter.Flush();
            }

            // Parse the response and bind the data to the UI controls
            var oDataResponse = batchRequest.GetResponse();

            using (var oDataReader = new ODataMessageReader(oDataResponse))
            {
                var oDataBatchReader = oDataReader.CreateODataBatchReader();

                while (oDataBatchReader.Read())
                {
                    switch (oDataBatchReader.State)
                    {
                    case ODataBatchReaderState.Initial:
                        // Optionally, handle the start of a batch payload.
                        break;

                    case ODataBatchReaderState.Operation:
                        // Encountered an operation (either top-level or in a changeset)
                        var operationResponse = oDataBatchReader.CreateOperationResponseMessage();

                        // Response ATOM markup parsing and presentation
                        using (var stream = operationResponse.GetStream())
                        {
                            switch (operationCount)
                            {
                            case 2:         // The "add new list" operation

                                if (operationResponse.StatusCode == 201)
                                {
                                    AddListResponse.Text = "Your list was created!";
                                }
                                else
                                {
                                    AddListResponse.Text = "Your list was not created. Status returned: " + operationResponse.StatusCode.ToString();
                                }

                                operationCount--;
                                break;

                            case 1:         // The "List of Lists" operation

                                // Bind data to the grid on the page.
                                // In a production app, check operationResponse.StatusCode and handle non-200 statuses.
                                // For simplicity, this sample assumes status 200 (the list items are returned).
                                List <XElement> entries    = SharePointDataHelpers.ListDataHelper.ExtractListItemsFromATOMResponse(stream);
                                var             itemTitles = SharePointDataHelpers.ListDataHelper.GetItemTitles(entries);
                                GridView3.DataSource = itemTitles;
                                GridView3.DataBind();
                                operationCount--;
                                break;
                            }
                        };
                        break;

                    case ODataBatchReaderState.ChangesetStart:
                        // Optionally, handle the start of a change set.
                        break;

                    case ODataBatchReaderState.ChangesetEnd:
                        // When this sample was created, SharePoint did not support "all or nothing" transactions.
                        // If that changes in the future this is where you would commit the transaction.
                        break;

                    case ODataBatchReaderState.Exception:
                        // In a producition app handle exeception. Omitted for simplicity in this sample app.
                        break;
                    }
                }
            }
            GridView3.Visible = true;
            TwoLists.Visible  = false;
        }
        internal static Tuple<HttpWebRequest, Stream> BuildRequestForTableBatchOperation(Uri uri, UriQueryBuilder builder, int? timeout, Uri baseUri, string tableName, TableBatchOperation batch, OperationContext ctx)
        {
            HttpWebRequest msg = BuildRequestCore(NavigationHelper.AppendPathToUri(uri, "$batch"), builder, "POST", timeout, ctx);

            // create the writer, indent for readability of the examples.  
            ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings()
            {
                CheckCharacters = false,   // sets this flag on the XmlWriter for ATOM  
                Version = ODataVersion.V2 // set the Odata version to use when writing the entry 
            };

            HttpWebRequestAdapterMessage adapterMsg = new HttpWebRequestAdapterMessage(msg);

            // Start Batch
            ODataMessageWriter odataWriter = new ODataMessageWriter(adapterMsg, writerSettings);
            ODataBatchWriter batchWriter = odataWriter.CreateODataBatchWriter();
            batchWriter.WriteStartBatch();

            bool isQuery = batch.Count == 1 && batch[0].OperationType == TableOperationType.Retrieve;

            // Query operations should not be inside changeset in payload
            if (!isQuery)
            {
                // Start Operation
                batchWriter.WriteStartChangeset();
                batchWriter.Flush();
            }

            foreach (TableOperation operation in batch)
            {
                string httpMethod = operation.OperationType == TableOperationType.Merge || operation.OperationType == TableOperationType.InsertOrMerge ? "MERGE" : operation.HttpMethod;

                ODataBatchOperationRequestMessage mimePartMsg = batchWriter.CreateOperationRequestMessage(httpMethod, operation.GenerateRequestURI(baseUri, tableName));

                // etag
                if (operation.OperationType == TableOperationType.Delete ||
                    operation.OperationType == TableOperationType.Replace ||
                    operation.OperationType == TableOperationType.Merge)
                {
                    mimePartMsg.SetHeader("If-Match", operation.Entity.ETag);
                }

                if (operation.OperationType != TableOperationType.Delete && operation.OperationType != TableOperationType.Retrieve)
                {
                    using (ODataMessageWriter batchEntryWriter = new ODataMessageWriter(mimePartMsg, writerSettings))
                    {
                        // Write entity
                        ODataWriter entryWriter = batchEntryWriter.CreateODataEntryWriter();
                        WriteOdataEntity(operation.Entity, operation.OperationType, ctx, entryWriter);
                    }
                }
            }

            if (!isQuery)
            {
                // End Operation
                batchWriter.WriteEndChangeset();
            }

            // End Batch
            batchWriter.WriteEndBatch();
            batchWriter.Flush();

            return new Tuple<HttpWebRequest, Stream>(adapterMsg.GetPopulatedMessage(), adapterMsg.GetStream());
        }
        private byte[] ServiceReadSingletonBatchRequestAndWriterBatchResponse(byte[] requestPayload)
        {
            IODataRequestMessage requestMessage = new InMemoryMessage() { Stream = new MemoryStream(requestPayload) };
            requestMessage.SetHeader("Content-Type", batchContentType);

            using (var messageReader = new ODataMessageReader(requestMessage, new ODataMessageReaderSettings(), this.userModel))
            {
                var responseStream = new MemoryStream();

                IODataResponseMessage responseMessage = new InMemoryMessage { Stream = responseStream };
                responseMessage.SetHeader("Content-Type", batchContentType);
                var messageWriter = new ODataMessageWriter(responseMessage);
                var batchWriter = messageWriter.CreateODataBatchWriter();
                batchWriter.WriteStartBatch();

                var batchReader = messageReader.CreateODataBatchReader();
                while (batchReader.Read())
                {
                    switch (batchReader.State)
                    {
                        case ODataBatchReaderState.Operation:
                            // Encountered an operation (either top-level or in a changeset)
                            var operationMessage = batchReader.CreateOperationRequestMessage();
                            if (operationMessage.Method == "PATCH")
                            {
                                var response = batchWriter.CreateOperationResponseMessage(operationMessage.ContentId);
                                response.StatusCode = 204;
                                response.SetHeader("Content-Type", "application/json;odata.metadata=none");
                            }
                            else if (operationMessage.Method == "GET")
                            {
                                var response = batchWriter.CreateOperationResponseMessage(null);
                                response.StatusCode = 200;
                                response.SetHeader("Content-Type", "application/json;");
                                var settings = new ODataMessageWriterSettings();
                                settings.SetServiceDocumentUri(new Uri(serviceDocumentUri));
                                using (var operationMessageWriter = new ODataMessageWriter(response, settings, this.userModel))
                                {
                                    var entryWriter = operationMessageWriter.CreateODataEntryWriter(this.singleton, this.webType);
                                    var entry = new ODataEntry() { TypeName = "NS.Web", Properties = new[] { new ODataProperty() { Name = "WebId", Value = 10 }, new ODataProperty() { Name = "Name", Value = "WebSingleton" } } };
                                    entryWriter.WriteStart(entry);
                                    entryWriter.WriteEnd();
                                }
                            }
                            else if (operationMessage.Method == "DELETE")
                            {
                                var response = batchWriter.CreateOperationResponseMessage(operationMessage.ContentId);
                                response.StatusCode = 500;
                            }

                            break;
                        case ODataBatchReaderState.ChangesetStart:
                            batchWriter.WriteStartChangeset();
                            break;
                        case ODataBatchReaderState.ChangesetEnd:
                            batchWriter.WriteEndChangeset();
                            break;
                    }
                }

                batchWriter.WriteEndBatch();
                responseStream.Position = 0;
                return responseStream.ToArray();
            }
        }
Example #40
0
        protected void Button3_Click(object sender, EventArgs e)
        {
            string accessToken = ((Button)sender).CommandArgument;
            Int16 operationCount = 0;

            if (IsPostBack)
            {
                // Get the host web's URL.
                sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);
            }

            // Create the parent request
            var batchRequest = new BatchODataRequest(String.Format("{0}/_api/", sharepointUrl)); // ctor adds "$batch"
            batchRequest.SetHeader("Authorization", "Bearer " + accessToken);

            using (var oDataMessageWriter = new ODataMessageWriter(batchRequest))
            {
                var oDataBatchWriter = oDataMessageWriter.CreateODataBatchWriter();
                oDataBatchWriter.WriteStartBatch();

                oDataBatchWriter.WriteStartChangeset();

                // Create the list adding operation
                var addListOperation = oDataBatchWriter.CreateOperationRequestMessage(
                    "POST", new Uri(sharepointUrl.ToString() + "/_api/lists"));
                addListOperation.SetHeader("Content-Type", "application/json;odata=verbose");

                // Write the body of the operation
                using (var oDataInsertWriter = new ODataMessageWriter(addListOperation))
                {
                    var entryWriter = oDataInsertWriter.CreateODataEntryWriter();

                    var insertionBody = new ODataEntry()
                    {
                        Properties = new[]
                            {
                                new ODataProperty() {Name = "Title", Value = NewList.Text},
                                new ODataProperty() {Name = "BaseTemplate", Value = "100"}
                            }
                    };

                    // Set the "__metadata" type property
                    insertionBody.TypeName = "SP.List";

                    entryWriter.WriteStart(insertionBody);
                    entryWriter.WriteEnd();
                }
                oDataBatchWriter.WriteEndChangeset();
                operationCount++;

                // Create the query operation
                var queryOperationMessage3 = oDataBatchWriter.CreateOperationRequestMessage(
                    "GET", new Uri(sharepointUrl.ToString() + "/_api/Web/lists"));
                operationCount++;

                oDataBatchWriter.WriteEndBatch();
                oDataBatchWriter.Flush();
            }

            // Parse the response and bind the data to the UI controls
            var oDataResponse = batchRequest.GetResponse();

            using (var oDataReader = new ODataMessageReader(oDataResponse))
            {
                var oDataBatchReader = oDataReader.CreateODataBatchReader();

                while (oDataBatchReader.Read())
                {
                    switch (oDataBatchReader.State)
                    {
                        case ODataBatchReaderState.Initial:
                            // Optionally, handle the start of a batch payload.
                            break;

                        case ODataBatchReaderState.Operation:
                            // Encountered an operation (either top-level or in a changeset)
                            var operationResponse = oDataBatchReader.CreateOperationResponseMessage();

                            // Response ATOM markup parsing and presentation
                            using (var stream = operationResponse.GetStream())
                            {

                                switch (operationCount)
                                {
                                    case 2: // The "add new list" operation
                                        
                                        if (operationResponse.StatusCode == 201)
                                        {
                                            AddListResponse.Text = "Your list was created!";
                                        }
                                        else
                                        {
                                            AddListResponse.Text = "Your list was not created. Status returned: " + operationResponse.StatusCode.ToString();
                                        }

                                        operationCount--;
                                        break;

                                    case 1: // The "List of Lists" operation

                                        // Bind data to the grid on the page.
                                           // In a production app, check operationResponse.StatusCode and handle non-200 statuses.
                                           // For simplicity, this sample assumes status 200 (the list items are returned).
                                        List<XElement> entries = SharePointDataHelpers.ListDataHelper.ExtractListItemsFromATOMResponse(stream);
                                        var itemTitles = SharePointDataHelpers.ListDataHelper.GetItemTitles(entries);
                                        GridView3.DataSource = itemTitles;
                                        GridView3.DataBind();
                                        operationCount--;
                                        break;
                                }
                            };
                            break;

                        case ODataBatchReaderState.ChangesetStart:
                            // Optionally, handle the start of a change set.
                            break;

                        case ODataBatchReaderState.ChangesetEnd:
                            // When this sample was created, SharePoint did not support "all or nothing" transactions. 
                            // If that changes in the future this is where you would commit the transaction.
                            break;

                        case ODataBatchReaderState.Exception:
                            // In a producition app handle exeception. Omitted for simplicity in this sample app.
                            break;
                    }
                }
            }
            GridView3.Visible = true;
            TwoLists.Visible = false;
        }
Example #41
0
            protected void Button2_Click(object sender, EventArgs e)
        {
            string accessToken = ((Button)sender).CommandArgument;
            Int16 listRetrievalCount = 0;

            if (IsPostBack)
            {
                // Get the host web's URL.
                sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);
            }
            
            // Create the parent request
            var batchRequest = new BatchODataRequest(String.Format("{0}/_api/", sharepointUrl)); // ctor adds "$batch"
            batchRequest.SetHeader("Authorization", "Bearer " + accessToken);
            
            using (var oDataMessageWriter = new ODataMessageWriter(batchRequest))
            {
                var oDataBatchWriter = oDataMessageWriter.CreateODataBatchWriter();
                oDataBatchWriter.WriteStartBatch();

               // Create the two child query operations.
               oDataBatchWriter.CreateOperationRequestMessage(
                    "GET", new Uri(sharepointUrl.ToString() + "/_api/Web/lists/getbytitle('Composed Looks')/items?$select=Title"));
                listRetrievalCount++;

                oDataBatchWriter.CreateOperationRequestMessage(
                   "GET", new Uri(sharepointUrl.ToString() + "/_api/Web/lists/getbytitle('User Information List')/items?$select=Title"));
                listRetrievalCount++;
                
                oDataBatchWriter.WriteEndBatch();
                oDataBatchWriter.Flush();
            }

            // Parse the response and bind the data to the UI controls
            var oDataResponse = batchRequest.GetResponse();

            using (var oDataReader = new ODataMessageReader(oDataResponse))
            {
                var oDataBatchReader = oDataReader.CreateODataBatchReader();

                while (oDataBatchReader.Read())
                {
                    switch (oDataBatchReader.State)
                    {
                        case ODataBatchReaderState.Initial:

                            // Optionally, handle the start of a batch payload.
                            break;
                        case ODataBatchReaderState.Operation:

                            // Start of an operation (either top-level or in a changeset)
                            var operationResponse = oDataBatchReader.CreateOperationResponseMessage();

                            // Response's ATOM markup parsing and presentation section
                            using (var stream = operationResponse.GetStream())
                            {
                                List<XElement> entries = SharePointDataHelpers.ListDataHelper.ExtractListItemsFromATOMResponse(stream);

                                var itemTitles = SharePointDataHelpers.ListDataHelper.GetItemTitles(entries);

                                // Bind data to the grid on the page.
                                   // In a production app, check operationResponse.StatusCode and handle non-200 statuses.
                                   // For simplicity, this sample assumes status 200 (the list items are returned).
                                switch (listRetrievalCount)
                                {
                                    case 2:
                                        GridView2.DataSource = itemTitles;
                                        GridView2.DataBind();
                                        listRetrievalCount--;
                                        break;

                                    case 1:
                                        GridView1.DataSource = itemTitles;
                                        GridView1.DataBind();
                                        listRetrievalCount--;
                                        break;
                                }
                            };
                            break;
                        case ODataBatchReaderState.ChangesetStart:
                            // Optionally, handle the start of a change set.
                            break;

                        case ODataBatchReaderState.ChangesetEnd:
                            // When this sample was created, SharePoint did not support "all or nothing" transactions. 
                            // If that changes in the future this is where you would commit the transaction.
                            break;

                        case ODataBatchReaderState.Exception:
                            // In a producition app handle exeception. Omitted for simplicity in this sample app.
                            break;
                    }
                }                
            }
            TwoLists.Visible = true;
        }
Example #42
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);
            }
        }
        protected void Button4_Click(object sender, EventArgs e)
        {
            string accessToken    = ((Button)sender).CommandArgument;
            Int16  operationCount = 0;

            if (IsPostBack)
            {
                // Get the host web's URL.
                sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);
            }

            // Create the parent request
            var batchRequest = new BatchODataRequest(sharepointUrl + "_api/"); // ctor adds "$batch"

            batchRequest.SetHeader("Authorization", "Bearer " + accessToken);

            using (var oDataMessageWriter = new ODataMessageWriter(batchRequest))
            {
                var oDataBatchWriter = oDataMessageWriter.CreateODataBatchWriter();
                oDataBatchWriter.WriteStartBatch();

                oDataBatchWriter.WriteStartChangeset();

                // Create the list deleting operation
                var deleteOperation = oDataBatchWriter.CreateOperationRequestMessage(
                    "DELETE", new Uri(sharepointUrl.ToString() + "_api/Web/lists/getbytitle(\'" + OldList.Text + "\')"));
                deleteOperation.SetHeader("If-Match", "\"1\"");

                oDataBatchWriter.WriteEndChangeset();
                operationCount++;

                // Create the query operation
                var queryOperationMessage3 = oDataBatchWriter.CreateOperationRequestMessage(
                    "GET", new Uri(sharepointUrl.ToString() + "_api/Web/lists"));
                operationCount++;

                oDataBatchWriter.WriteEndBatch();
                oDataBatchWriter.Flush();
            }

            // Parse the response and bind the data to the UI controls
            var oDataResponse = batchRequest.GetResponse();

            using (var oDataReader = new ODataMessageReader(oDataResponse))
            {
                var oDataBatchReader = oDataReader.CreateODataBatchReader();

                while (oDataBatchReader.Read())
                {
                    switch (oDataBatchReader.State)
                    {
                    case ODataBatchReaderState.Initial:
                        // Optionally, handle the start of a batch payload.
                        break;

                    case ODataBatchReaderState.Operation:
                        // Encountered an operation (either top-level or in a changeset)
                        var operationResponse = oDataBatchReader.CreateOperationResponseMessage();

                        // Response ATOM markup parsing and presentation
                        using (var stream = operationResponse.GetStream())
                        {
                            switch (operationCount)
                            {
                            case 2:         // The "delete list" operation

                                if (operationResponse.StatusCode == 200)
                                {
                                    DeleteListResponse.Text = "Your list was deleted!";
                                }
                                else
                                {
                                    DeleteListResponse.Text = "Your list was not deleted. Status returned: " + operationResponse.StatusCode.ToString();
                                }

                                operationCount--;
                                break;

                            case 1:         // The "List of Lists" operation

                                // Bind data to the grid on the page.
                                // In a production app, check operationResponse.StatusCode and handle non-200 statuses.
                                // For simplicity, this sample assumes status 200 (the list items are returned).
                                List <XElement> entries    = SharePointDataHelpers.ListDataHelper.ExtractListItemsFromATOMResponse(stream);
                                var             itemTitles = SharePointDataHelpers.ListDataHelper.GetItemTitles(entries);
                                GridView4.DataSource = itemTitles;
                                GridView4.DataBind();
                                operationCount--;
                                break;
                            }
                        };
                        break;

                    case ODataBatchReaderState.ChangesetStart:
                        // Optionally, handle the start of a change set.
                        break;

                    case ODataBatchReaderState.ChangesetEnd:
                        // When this sample was created, SharePoint did not support "all or nothing" transactions.
                        // If that changes in the future this is where you would commit the transaction.
                        break;

                    case ODataBatchReaderState.Exception:
                        // In a producition app handle exeception. Omitted for simplicity in this sample app.
                        break;
                    }
                }
            }

            GridView3.Visible = false;
        }
Example #44
0
        /// <summary>
        /// Generate the batch request for all changes to save.
        /// </summary>
        /// <returns>Returns the instance of ODataRequestMessage containing all the headers and payload for the batch request.</returns>
        private ODataRequestMessageWrapper GenerateBatchRequest()
        {
            if (this.ChangedEntries.Count == 0 && this.Queries == null)
            {
                this.SetCompleted();
                return(null);
            }

            ODataRequestMessageWrapper batchRequestMessage = this.CreateBatchRequest();

            // we need to fire request after the headers have been written, but before we write the payload
            batchRequestMessage.FireSendingRequest2(null);

            using (ODataMessageWriter messageWriter = Serializer.CreateMessageWriter(batchRequestMessage, this.RequestInfo, false /*isParameterPayload*/))
            {
                this.batchWriter = messageWriter.CreateODataBatchWriter();
                this.batchWriter.WriteStartBatch();

                if (this.Queries != null)
                {
                    foreach (DataServiceRequest query in this.Queries)
                    {
                        QueryComponents queryComponents = query.QueryComponents(this.RequestInfo.Model);
                        Uri             requestUri      = this.RequestInfo.BaseUriResolver.GetOrCreateAbsoluteUri(queryComponents.Uri);

                        Debug.Assert(requestUri != null, "request uri is null");
                        Debug.Assert(requestUri.IsAbsoluteUri, "request uri is not absolute uri");

                        HeaderCollection headers = new HeaderCollection();

                        headers.SetRequestVersion(queryComponents.Version, this.RequestInfo.MaxProtocolVersionAsVersion);

                        this.RequestInfo.Format.SetRequestAcceptHeaderForQuery(headers, queryComponents);

                        ODataRequestMessageWrapper batchOperationRequestMessage = this.CreateRequestMessage(XmlConstants.HttpMethodGet, requestUri, headers, this.RequestInfo.HttpStack, null /*descriptor*/, null /*contentId*/);

                        batchOperationRequestMessage.FireSendingEventHandlers(null /*descriptor*/);
                    }
                }
                else if (0 < this.ChangedEntries.Count)
                {
                    if (Util.IsBatchWithSingleChangeset(this.Options))
                    {
                        this.batchWriter.WriteStartChangeset();
                    }

                    var model = this.RequestInfo.Model;

                    for (int i = 0; i < this.ChangedEntries.Count; ++i)
                    {
                        if (Util.IsBatchWithIndependentOperations(this.Options))
                        {
                            this.batchWriter.WriteStartChangeset();
                        }

                        Descriptor descriptor = this.ChangedEntries[i];
                        if (descriptor.ContentGeneratedForSave)
                        {
                            continue;
                        }

                        EntityDescriptor entityDescriptor = descriptor as EntityDescriptor;
                        if (descriptor.DescriptorKind == DescriptorKind.Entity)
                        {
                            if (entityDescriptor.State == EntityStates.Added)
                            {
                                // We don't support adding MLE/MR in batch mode
                                ClientTypeAnnotation type = model.GetClientTypeAnnotation(model.GetOrCreateEdmType(entityDescriptor.Entity.GetType()));
                                if (type.IsMediaLinkEntry || entityDescriptor.IsMediaLinkEntry)
                                {
                                    throw Error.NotSupported(Strings.Context_BatchNotSupportedForMediaLink);
                                }
                            }
                            else if (entityDescriptor.State == EntityStates.Unchanged || entityDescriptor.State == EntityStates.Modified)
                            {
                                // We don't support PUT for the MR in batch mode
                                // It's OK to PUT the MLE alone inside a batch mode though
                                if (entityDescriptor.SaveStream != null)
                                {
                                    throw Error.NotSupported(Strings.Context_BatchNotSupportedForMediaLink);
                                }
                            }
                        }
                        else if (descriptor.DescriptorKind == DescriptorKind.NamedStream)
                        {
                            // Similar to MR, we do not support adding named streams in batch mode.
                            throw Error.NotSupported(Strings.Context_BatchNotSupportedForNamedStreams);
                        }

                        ODataRequestMessageWrapper operationRequestMessage;
                        if (descriptor.DescriptorKind == DescriptorKind.Entity)
                        {
                            operationRequestMessage = this.CreateRequest(entityDescriptor);
                        }
                        else
                        {
                            operationRequestMessage = this.CreateRequest((LinkDescriptor)descriptor);
                        }

                        // we need to fire request after the headers have been written, but before we write the payload
                        operationRequestMessage.FireSendingRequest2(descriptor);

                        this.CreateChangeData(i, operationRequestMessage);

                        if (Util.IsBatchWithIndependentOperations(this.Options))
                        {
                            this.batchWriter.WriteEndChangeset();
                        }
                    }

                    if (Util.IsBatchWithSingleChangeset(this.Options))
                    {
                        this.batchWriter.WriteEndChangeset();
                    }
                }

                this.batchWriter.WriteEndBatch();
                this.batchWriter.Flush();
            }

            Debug.Assert(this.ChangedEntries.All(o => o.ContentGeneratedForSave), "didn't generated content for all entities/links");
            return(batchRequestMessage);
        }
        private byte[] ClientWriteSingletonBatchRequest()
        {
            var stream = new MemoryStream();

            IODataRequestMessage requestMessage = new InMemoryMessage { Stream = stream };
            requestMessage.SetHeader("Content-Type", batchContentType);

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

                batchWriter.WriteStartBatch();

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

                // Header modification on inner payload.
                queryOperationMessage.SetHeader("Accept", "application/json;odata.metadata=full");

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

                // Create a update operation in the changeset.
                var updateOperationMessage = batchWriter.CreateOperationRequestMessage("PATCH", new Uri(serviceDocumentUri + "/MySingleton"), "1");

                // Use a new message writer to write the body of this operation.
                using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage))
                {
                    var entryWriter = operationMessageWriter.CreateODataEntryWriter();
                    var entry = new ODataEntry() { TypeName = "NS.Web", Properties = new[] { new ODataProperty() { Name = "WebId", Value = 10 }, new ODataProperty() { Name = "Name", Value = "SingletonWeb" } } };
                    entryWriter.WriteStart(entry);
                    entryWriter.WriteEnd();
                }

                updateOperationMessage = batchWriter.CreateOperationRequestMessage("PATCH", new Uri(serviceDocumentUri + "/MySingleton"), "2");

                using (var operationMessageWriter = new ODataMessageWriter(updateOperationMessage))
                {
                    var entryWriter = operationMessageWriter.CreateODataEntryWriter();
                    var entry = new ODataEntry() { TypeName = "NS.Web", Properties = new[] { new ODataProperty() { Name = "WebId", Value = 111 } } };
                    entryWriter.WriteStart(entry);
                    entryWriter.WriteEnd();
                }

                batchWriter.WriteEndChangeset();

                // Write a query operation.
                queryOperationMessage = batchWriter.CreateOperationRequestMessage("GET", new Uri(serviceDocumentUri + "/MySingleton/WebId"), /*contentId*/ null);

                queryOperationMessage.SetHeader("Accept", "application/json;odata.metadata=full");

                // DELETE singleton, invalid
                batchWriter.WriteStartChangeset();
                batchWriter.CreateOperationRequestMessage("DELETE", new Uri(serviceDocumentUri + "MySingleton"), "1");
                batchWriter.WriteEndChangeset();

                batchWriter.WriteEndBatch();

                stream.Position = 0;
                return stream.ToArray();
            }
        }