From 0cf10e30155edefd61b25457620b467f5676ed43 Mon Sep 17 00:00:00 2001 From: Adrian Piaskowski <131464532+apiaskowski@users.noreply.github.com> Date: Tue, 25 Jul 2023 18:05:36 +0200 Subject: [PATCH] Fixed the handling of empty http attributes in Batch Requests (#2705) --- ...sonLightBatchPayloadItemPropertiesCache.cs | 4 +- .../ODataJsonLightBatchReaderTests.cs | 72 +++++++++++++++++++ 2 files changed, 74 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.OData.Core/JsonLight/ODataJsonLightBatchPayloadItemPropertiesCache.cs b/src/Microsoft.OData.Core/JsonLight/ODataJsonLightBatchPayloadItemPropertiesCache.cs index 38de20f84c..c526644e6a 100644 --- a/src/Microsoft.OData.Core/JsonLight/ODataJsonLightBatchPayloadItemPropertiesCache.cs +++ b/src/Microsoft.OData.Core/JsonLight/ODataJsonLightBatchPayloadItemPropertiesCache.cs @@ -273,7 +273,7 @@ private void ScanJsonProperties() while (this.jsonReader.NodeType != JsonNodeType.EndObject) { string headerName = this.jsonReader.ReadPropertyName(); - string headerValue = this.jsonReader.ReadPrimitiveValue().ToString(); + string headerValue = this.jsonReader.ReadPrimitiveValue()?.ToString(); // Throw an ODataException, if a duplicate header was detected if (headers.ContainsKeyOrdinal(headerName)) @@ -425,7 +425,7 @@ await this.asynchronousJsonReader.ReadStartObjectAsync() { string headerName = await this.asynchronousJsonReader.ReadPropertyNameAsync() .ConfigureAwait(false); - string headerValue = (await this.asynchronousJsonReader.ReadPrimitiveValueAsync().ConfigureAwait(false)).ToString(); + string headerValue = (await this.asynchronousJsonReader.ReadPrimitiveValueAsync().ConfigureAwait(false))?.ToString(); // Throw an ODataException, if a duplicate header was detected if (headers.ContainsKeyOrdinal(headerName)) diff --git a/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/ODataJsonLightBatchReaderTests.cs b/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/ODataJsonLightBatchReaderTests.cs index 1bf1432bf4..982a06b056 100644 --- a/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/ODataJsonLightBatchReaderTests.cs +++ b/test/FunctionalTests/Microsoft.OData.Core.Tests/JsonLight/ODataJsonLightBatchReaderTests.cs @@ -363,6 +363,78 @@ await DoReadAsync( isResponse: false); } + [Fact] + public void ReadBatchRequestWithNullHeaders() + { + var payload = "{\"requests\": [{" + + "\"id\": \"1\"," + + "\"method\": \"POST\"," + + "\"url\": \"http://tempuri.org/Customers\"," + + "\"headers\": {\"odata-version\":\"4.0\",\"content-type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\",\"null-header\":null}, " + + "\"body\": {\"@odata.type\":\"#NS.Customer\",\"Id\":1,\"Name\":\"Customer 1\",\"Type\":\"Retail\"}}]}"; + + SetupJsonLightBatchReaderAndRunTest( + payload, + (jsonLightBatchReader) => + { + try + { + while (jsonLightBatchReader.Read()) + { + if (jsonLightBatchReader.State == ODataBatchReaderState.Operation) + { + var operationRequestMessage = jsonLightBatchReader.CreateOperationRequestMessage(); + // Verify that the Property "null-header" exists and it's value is set to NULL + var nullHeaderProperty = operationRequestMessage.Headers.FirstOrDefault(p => p.Key == "null-header"); + Assert.NotNull(nullHeaderProperty.Key); + Assert.Null(nullHeaderProperty.Value); + } + } + } + catch (NullReferenceException ex) + { + Assert.False(true, ex.Message); + } + }, + isResponse: false); + } + + [Fact] + public async Task ReadBatchRequestWithNullHeadersAsync() + { + var payload = "{\"requests\": [{" + + "\"id\": \"1\"," + + "\"method\": \"POST\"," + + "\"url\": \"http://tempuri.org/Customers\"," + + "\"headers\": {\"odata-version\":\"4.0\",\"content-type\":\"application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8\",\"null-header\":null}, " + + "\"body\": {\"@odata.type\":\"#NS.Customer\",\"Id\":1,\"Name\":\"Customer 1\",\"Type\":\"Retail\"}}]}"; + + await SetupJsonLightBatchReaderAndRunTestAsync( + payload, + async (jsonLightBatchReader) => + { + try + { + while (await jsonLightBatchReader.ReadAsync()) + { + if (jsonLightBatchReader.State == ODataBatchReaderState.Operation) + { + var operationRequestMessage = await jsonLightBatchReader.CreateOperationRequestMessageAsync(); + // Verify that the Property "null-header" exists and it's value is set to NULL + var nullHeaderProperty = operationRequestMessage.Headers.FirstOrDefault(p => p.Key == "null-header"); + Assert.NotNull(nullHeaderProperty.Key); + Assert.Null(nullHeaderProperty.Value); + } + } + } + catch (NullReferenceException ex) + { + Assert.False(true, ex.Message); + } + }, + isResponse: false); + } + [Fact] public void ReadBatchRequestWithDuplicateProperties() {