Ejemplo n.º 1
0
        /// <summary>
        /// Creates an <see cref="ODataBatchOperationRequestMessage"/> for writing an operation of a batch request.
        /// </summary>
        /// <param name="method">The Http method to be used for this request operation.</param>
        /// <param name="uri">The Uri to be used for this request operation.</param>
        /// <param name="contentId">The (optional) content ID to be included in this request operation.</param>
        /// <returns>The message that can be used to write the request operation.</returns>
        public ODataBatchOperationRequestMessage CreateOperationRequestMessage(HttpMethod method, Uri uri, string contentId)
        {
            this.ValidateWriterReady();

            if (this.writingResponse)
            {
                this.ThrowODataException(Strings.ODataBatchWriter_CannotCreateRequestOperationWhenWritingResponse);
            }

            if (this.changeSetBoundary == null)
            {
                // only allow GET requests for query operations
                if (method != HttpMethod.Get)
                {
                    this.ThrowODataException(Strings.ODataBatchWriter_InvalidHttpMethodForQueryOperation(method.ToText()));
                }

                // do not allow content-id for query operations
                if (contentId != null)
                {
                    this.ThrowODataException(Strings.ODataBatchWriter_ContentIdNotSupportedForQueryOperations(contentId));
                }

                this.InterceptException(this.IncreaseBatchSize);
            }
            else
            {
                // allow all methods except for GET
                if (method == HttpMethod.Get)
                {
                    this.ThrowODataException(Strings.ODataBatchWriter_InvalidHttpMethodForChangeSetRequest(method.ToText()));
                }

                this.InterceptException(this.IncreaseChangeSetSize);
            }

            ExceptionUtils.CheckArgumentNotNull(uri, "uri");

            this.InterceptException(() => uri = ODataBatchWriterUtils.BuildAbsoluteUri(uri, this.settings.BaseUri));

            // write pending message data (headers, response line) for a previously unclosed message/request
            this.WritePendingMessageData(true);

            // create the new request operation
            this.CurrentOperationRequestMessage = new ODataBatchOperationRequestMessage(this.outputStream, method, uri, this);
            this.SetState(BatchWriterState.OperationCreated);

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

            // write the headers, request line and (optional) Content-ID
            ODataBatchWriterUtils.WriteRequestPreamble(this.batchWriter, method, uri, contentId);

            return(this.CurrentOperationRequestMessage);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Writes the start boundary for an operation. This is either the batch or the changeset boundary.
 /// </summary>
 private void WriteStartBoundaryForOperation()
 {
     if (this.changeSetBoundary == null)
     {
         ODataBatchWriterUtils.WriteStartBoundary(this.batchWriter, this.batchBoundary);
         this.batchStartBoundaryWritten = true;
     }
     else
     {
         ODataBatchWriterUtils.WriteStartBoundary(this.batchWriter, this.changeSetBoundary);
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Ends an active changeset; this can only be called after WriteStartChangeset and only once for each changeset.
        /// </summary>
        public void WriteEndChangeset()
        {
            this.ValidateWriterReady();

            // write pending message data (headers, response line) for a previously unclosed message/request
            this.WritePendingMessageData(true);

            // change the state first so we validate the change set boundary before attempting to write it.
            string currentChangeSetBoundary = this.changeSetBoundary;

            this.SetState(BatchWriterState.ChangeSetCompleted);

            // write the end boundary for the change set
            ODataBatchWriterUtils.WriteEndBoundary(this.batchWriter, currentChangeSetBoundary);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Ends a batch; can only be called after WriteStartBatch has been called and if no other active changeset or operation exist.
        /// </summary>
        public void WriteEndBatch()
        {
            this.ValidateWriterReady();

            // write the start boundary for the batch if not written
            if (!this.batchStartBoundaryWritten)
            {
                Debug.Assert(this.CurrentOperationMessage == null, "If not batch boundary was written we must not have an active message.");
                ODataBatchWriterUtils.WriteStartBoundary(this.batchWriter, this.batchBoundary);
            }

            // write pending message data (headers, response line) for a previously unclosed message/request
            this.WritePendingMessageData(true);

            this.SetState(BatchWriterState.BatchCompleted);

            // write the end boundary for the batch
            ODataBatchWriterUtils.WriteEndBoundary(this.batchWriter, this.batchBoundary);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Creates an <see cref="ODataBatchOperationResponseMessage"/> for writing an operation of a batch response.
        /// </summary>
        /// <returns>The message that can be used to write the response operation.</returns>
        public ODataBatchOperationResponseMessage CreateOperationResponseMessage()
        {
            this.ValidateWriterReady();

            if (!this.writingResponse)
            {
                this.ThrowODataException(Strings.ODataBatchWriter_CannotCreateResponseOperationWhenWritingRequest);
            }

            this.WritePendingMessageData(true);

            this.CurrentOperationResponseMessage = new ODataBatchOperationResponseMessage(this.outputStream, this);
            this.SetState(BatchWriterState.OperationCreated);

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

            // write the headers, request line and (optional) Content-ID
            ODataBatchWriterUtils.WriteResponsePreamble(this.batchWriter);

            return(this.CurrentOperationResponseMessage);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Starts a new changeset; can only be called after WriteStartBatch and if no other active operation or changeset exists.
        /// </summary>
        public void WriteStartChangeset()
        {
            this.ValidateWriterReady();

            // write pending message data (headers, response line) for a previously unclosed message/request
            this.WritePendingMessageData(true);

            // important to do this first since it will set up the change set boundary.
            this.SetState(BatchWriterState.ChangeSetStarted);
            Debug.Assert(this.changeSetBoundary != null, "this.changeSetBoundary != null");

            // reset the size of the current changeset and increase the size of the batch
            this.ResetChangeSetSize();
            this.InterceptException(this.IncreaseBatchSize);

            // write the boundary string
            ODataBatchWriterUtils.WriteStartBoundary(this.batchWriter, this.batchBoundary);
            this.batchStartBoundaryWritten = true;

            // write the change set headers
            ODataBatchWriterUtils.WriteChangeSetPreamble(this.batchWriter, this.changeSetBoundary);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Sets a new writer state; verifies that the transition from the current state into new state is valid.
        /// </summary>
        /// <param name="newState">The writer state to transition into.</param>
        private void SetState(BatchWriterState newState)
        {
            this.InterceptException(() => this.ValidateTransition(newState));

            switch (newState)
            {
            case BatchWriterState.BatchStarted:
                Debug.Assert(!this.batchStartBoundaryWritten, "The batch boundary must not be written before calling WriteStartBatch.");
                break;

            case BatchWriterState.ChangeSetStarted:
                Debug.Assert(this.changeSetBoundary == null, "this.changeSetBoundary == null");
                this.changeSetBoundary = ODataBatchWriterUtils.CreateChangeSetBoundary(this.writingResponse);
                break;

            case BatchWriterState.ChangeSetCompleted:
                Debug.Assert(this.changeSetBoundary != null, "this.changeSetBoundary != null");
                this.changeSetBoundary = null;
                break;
            }

            this.state = newState;
        }