/// <summary> /// Creates a batch reader stream backed by memory stream containing data the current /// Json object the reader is pointing at. /// Current supported data types are Json and binary types. /// </summary> /// <param name="contentTypeHeader">The content-type header value of the request.</param> /// <returns>The memory stream.</returns> private ODataJsonLightBatchBodyContentReaderStream CreateJsonPayloadBodyContentStream(string contentTypeHeader) { // Serialization of json object to batch buffer. ODataJsonLightBatchBodyContentReaderStream stream = new ODataJsonLightBatchBodyContentReaderStream(listener); this.isStreamPopulated = stream.PopulateBodyContent(this.jsonReader, contentTypeHeader); return(stream); }
/// <summary> /// Asynchronously creates a batch reader stream backed by memory stream containing data the current /// Json object the reader is pointing at. /// Current supported data types are Json and binary types. /// </summary> /// <param name="contentTypeHeader">The content-type header value of the request.</param> /// <returns> /// A task that represents the asynchronous operation. /// The value of the TResult parameter contains the wrapper stream backed by memory stream. /// </returns> private async Task <ODataJsonLightBatchBodyContentReaderStream> CreateJsonPayloadBodyContentStreamAsync(string contentTypeHeader) { // Serialization of json object to batch buffer. ODataJsonLightBatchBodyContentReaderStream stream = new ODataJsonLightBatchBodyContentReaderStream(listener); this.isStreamPopulated = await stream.PopulateBodyContentAsync(this.asynchronousJsonReader, contentTypeHeader) .ConfigureAwait(false); return(stream); }
/// <summary> /// Wrapper method with validation to scan the Json object for known properties. /// </summary> private void ScanJsonProperties() { Debug.Assert(this.jsonReader != null, "this.jsonReaders != null"); Debug.Assert(this.jsonProperties == null, "this.jsonProperties == null"); this.jsonProperties = new Dictionary <string, object>(); string contentTypeHeader = null; ODataJsonLightBatchBodyContentReaderStream bodyContentStream = null; try { // Request object start. this.jsonReader.ReadStartObject(); while (this.jsonReader.NodeType != JsonNodeType.EndObject) { // Convert to upper case to support case-insensitive request property names string propertyName = Normalize(this.jsonReader.ReadPropertyName()); switch (propertyName) { case PropertyNameId: case PropertyNameAtomicityGroup: case PropertyNameMethod: case PropertyNameUrl: { jsonProperties.Add(propertyName, this.jsonReader.ReadStringValue()); } break; case PropertyNameStatus: { jsonProperties.Add(propertyName, this.jsonReader.ReadPrimitiveValue()); } break; case PropertyNameDependsOn: { IList <string> dependsOnIds = new List <string>(); this.jsonReader.ReadStartArray(); while (this.jsonReader.NodeType != JsonNodeType.EndArray) { dependsOnIds.Add(this.jsonReader.ReadStringValue()); } this.jsonReader.ReadEndArray(); jsonProperties.Add(propertyName, dependsOnIds); } break; case PropertyNameHeaders: { ODataBatchOperationHeaders headers = new ODataBatchOperationHeaders(); // Use empty string (non-null value) to indicate that content-type header has been processed. contentTypeHeader = ""; this.jsonReader.ReadStartObject(); while (this.jsonReader.NodeType != JsonNodeType.EndObject) { string headerName = this.jsonReader.ReadPropertyName(); string headerValue = this.jsonReader.ReadPrimitiveValue().ToString(); // Remember the Content-Type header value. if (headerName.Equals(ODataConstants.ContentTypeHeader, StringComparison.OrdinalIgnoreCase)) { contentTypeHeader = headerValue; } headers.Add(headerName, headerValue); } this.jsonReader.ReadEndObject(); jsonProperties.Add(propertyName, headers); if (!this.isStreamPopulated && bodyContentStream != null) { // Populate the stream now since the body content has been cached and we now have content-type. bodyContentStream.PopulateCachedBodyContent(contentTypeHeader); } } break; case PropertyNameBody: { bodyContentStream = CreateJsonPayloadBodyContentStream(contentTypeHeader); jsonProperties.Add(propertyName, bodyContentStream); } break; default: { throw new ODataException(string.Format( CultureInfo.InvariantCulture, "Unknown property name '{0}' for message in batch", propertyName)); } } } // Request object end. this.jsonReader.ReadEndObject(); } finally { // We don't need to use the Json reader anymore. this.jsonReader = null; } }
/// <summary> /// Wrapper method with validation to asynchronously scan the JSON object for known properties. /// </summary> /// <returns>A task that represents the asynchronous read operation.</returns> private async Task ScanJsonPropertiesAsync() { Debug.Assert(this.asynchronousJsonReader != null, $"{nameof(this.asynchronousJsonReader)} != null"); Debug.Assert(this.jsonProperties == null, $"{nameof(this.jsonProperties)} == null"); this.jsonProperties = new Dictionary <string, object>(); string contentTypeHeader = null; ODataJsonLightBatchBodyContentReaderStream bodyContentStream = null; try { // Request object start. await this.asynchronousJsonReader.ReadStartObjectAsync() .ConfigureAwait(false); while (this.asynchronousJsonReader.NodeType != JsonNodeType.EndObject) { // Convert to upper case to support case-insensitive request property names string propertyName = Normalize(await this.asynchronousJsonReader.ReadPropertyNameAsync().ConfigureAwait(false)); switch (propertyName) { case PropertyNameId: case PropertyNameAtomicityGroup: case PropertyNameMethod: case PropertyNameUrl: jsonProperties.Add( propertyName, await this.asynchronousJsonReader.ReadStringValueAsync().ConfigureAwait(false)); break; case PropertyNameStatus: jsonProperties.Add( propertyName, await this.asynchronousJsonReader.ReadPrimitiveValueAsync().ConfigureAwait(false)); break; case PropertyNameDependsOn: List <string> dependsOnIds = new List <string>(); await this.asynchronousJsonReader.ReadStartArrayAsync() .ConfigureAwait(false); while (this.asynchronousJsonReader.NodeType != JsonNodeType.EndArray) { dependsOnIds.Add(await this.asynchronousJsonReader.ReadStringValueAsync().ConfigureAwait(false)); } await this.asynchronousJsonReader.ReadEndArrayAsync() .ConfigureAwait(false); jsonProperties.Add(propertyName, dependsOnIds); break; case PropertyNameHeaders: ODataBatchOperationHeaders headers = new ODataBatchOperationHeaders(); // Use empty string (non-null value) to indicate that content-type header has been processed. contentTypeHeader = ""; await this.asynchronousJsonReader.ReadStartObjectAsync() .ConfigureAwait(false); while (this.asynchronousJsonReader.NodeType != JsonNodeType.EndObject) { string headerName = await this.asynchronousJsonReader.ReadPropertyNameAsync() .ConfigureAwait(false); string headerValue = (await this.asynchronousJsonReader.ReadPrimitiveValueAsync().ConfigureAwait(false)).ToString(); // Remember the Content-Type header value. if (headerName.Equals(ODataConstants.ContentTypeHeader, StringComparison.OrdinalIgnoreCase)) { contentTypeHeader = headerValue; } headers.Add(headerName, headerValue); } await this.asynchronousJsonReader.ReadEndObjectAsync() .ConfigureAwait(false); jsonProperties.Add(propertyName, headers); if (!this.isStreamPopulated && bodyContentStream != null) { // Populate the stream now since the body content has been cached and we now have content-type. await bodyContentStream.PopulateCachedBodyContentAsync(contentTypeHeader) .ConfigureAwait(false); } break; case PropertyNameBody: bodyContentStream = await CreateJsonPayloadBodyContentStreamAsync(contentTypeHeader) .ConfigureAwait(false); jsonProperties.Add(propertyName, bodyContentStream); break; default: throw new ODataException(Strings.ODataJsonLightBatchPayloadItemPropertiesCache_UnknownPropertyForMessageInBatch(propertyName)); } } // Request object end. await this.asynchronousJsonReader.ReadEndObjectAsync() .ConfigureAwait(false); } finally { // We don't need to use the Json reader anymore. this.asynchronousJsonReader = null; } }