From 833078485d4564e4fe78e5fc83e420511fea8b95 Mon Sep 17 00:00:00 2001 From: Lilian Kasem Date: Mon, 16 Dec 2024 10:41:32 -0800 Subject: [PATCH 1/3] Use DeserializeAsync and update release notes --- extensions/Worker.Extensions.Http/release_notes.md | 2 +- .../src/DefaultFromBodyConversionFeature.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/Worker.Extensions.Http/release_notes.md b/extensions/Worker.Extensions.Http/release_notes.md index 8f2985eb5..cac20a938 100644 --- a/extensions/Worker.Extensions.Http/release_notes.md +++ b/extensions/Worker.Extensions.Http/release_notes.md @@ -6,4 +6,4 @@ ### Microsoft.Azure.Functions.Worker.Extensions.Http -- +- The 'FromBody' converter now utilizes `DeserializeAsync` for deserializing JSON content from the request body, enhancing support for asynchronous deserialization. (#) diff --git a/extensions/Worker.Extensions.Http/src/DefaultFromBodyConversionFeature.cs b/extensions/Worker.Extensions.Http/src/DefaultFromBodyConversionFeature.cs index c98d1950a..8e3c90a95 100644 --- a/extensions/Worker.Extensions.Http/src/DefaultFromBodyConversionFeature.cs +++ b/extensions/Worker.Extensions.Http/src/DefaultFromBodyConversionFeature.cs @@ -46,7 +46,7 @@ internal class DefaultFromBodyConversionFeature : IFromBodyConversionFeature return ConvertBodyAsync(requestData, context, targetType); } - private static ValueTask ConvertBodyAsync(HttpRequestData requestData, FunctionContext context, Type targetType) + private static async ValueTask ConvertBodyAsync(HttpRequestData requestData, FunctionContext context, Type targetType) { object? result; @@ -68,7 +68,7 @@ internal class DefaultFromBodyConversionFeature : IFromBodyConversionFeature ObjectSerializer serializer = requestData.FunctionContext.InstanceServices.GetService>()?.Value?.Serializer ?? throw new InvalidOperationException("A serializer is not configured for the worker."); - result = serializer.Deserialize(requestData.Body, targetType, context.CancellationToken); + result = await serializer.DeserializeAsync(requestData.Body, targetType, context.CancellationToken); } else { From 3fdf14f8acf5891da3259ca0277a1aa3833a5e48 Mon Sep 17 00:00:00 2001 From: Lilian Kasem Date: Thu, 19 Dec 2024 16:02:31 -0800 Subject: [PATCH 2/3] Refactor ConvertBodyAsync --- .../src/DefaultFromBodyConversionFeature.cs | 52 ++++++------------- 1 file changed, 16 insertions(+), 36 deletions(-) diff --git a/extensions/Worker.Extensions.Http/src/DefaultFromBodyConversionFeature.cs b/extensions/Worker.Extensions.Http/src/DefaultFromBodyConversionFeature.cs index 8e3c90a95..767832406 100644 --- a/extensions/Worker.Extensions.Http/src/DefaultFromBodyConversionFeature.cs +++ b/extensions/Worker.Extensions.Http/src/DefaultFromBodyConversionFeature.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using System.IO; using System.Linq; using System.Net.Http.Headers; using System.Threading; @@ -46,44 +47,23 @@ internal class DefaultFromBodyConversionFeature : IFromBodyConversionFeature return ConvertBodyAsync(requestData, context, targetType); } - private static async ValueTask ConvertBodyAsync(HttpRequestData requestData, FunctionContext context, Type targetType) + private static async ValueTask ConvertBodyAsync(HttpRequestData requestData, FunctionContext context, Type targetType) => targetType switch { - object? result; - - if (targetType == typeof(string)) - { - result = requestData.ReadAsString(); - } - else if (targetType == typeof(byte[])) - { - result = ReadBytes(requestData, context.CancellationToken); - } - else if (targetType == typeof(Memory)) - { - Memory bytes = ReadBytes(requestData, context.CancellationToken); - result = bytes; - } - else if (HasJsonContentType(requestData)) - { - ObjectSerializer serializer = requestData.FunctionContext.InstanceServices.GetService>()?.Value?.Serializer - ?? throw new InvalidOperationException("A serializer is not configured for the worker."); - - result = await serializer.DeserializeAsync(requestData.Body, targetType, context.CancellationToken); - } - else - { - throw new InvalidOperationException($"The type '{targetType}' is not supported by the '{nameof(DefaultFromBodyConversionFeature)}'."); - } - - return new ValueTask(result); - } - - private static byte[] ReadBytes(HttpRequestData requestData, CancellationToken cancellationToken) + _ when targetType == typeof(string) => await requestData.ReadAsStringAsync(), + _ when targetType == typeof(byte[]) => await ReadBytesAsync(requestData), + _ when targetType == typeof(Memory) => new Memory(await ReadBytesAsync(requestData)), + _ when HasJsonContentType(requestData) => + await (requestData.FunctionContext.InstanceServices.GetService>()?.Value?.Serializer + ?? throw new InvalidOperationException("A serializer is not configured for the worker.")) + .DeserializeAsync(requestData.Body, targetType, context.CancellationToken), + _ => throw new InvalidOperationException($"The type '{targetType}' is not supported by the '{nameof(DefaultFromBodyConversionFeature)}'.") + }; + + private static async Task ReadBytesAsync(HttpRequestData requestData) { - var bytes = new byte[requestData.Body.Length]; - requestData.Body.Read(bytes, 0, bytes.Length); - - return bytes; + using var memoryStream = new MemoryStream(); + await requestData.Body.CopyToAsync(memoryStream); + return memoryStream.ToArray(); } private static bool HasJsonContentType(HttpRequestData request) From 25e2f7a243fac5c7df90b0236285a9ec93e1f090 Mon Sep 17 00:00:00 2001 From: Lilian Kasem Date: Mon, 6 Jan 2025 10:22:59 -0800 Subject: [PATCH 3/3] Update release notes --- extensions/Worker.Extensions.Http/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/Worker.Extensions.Http/release_notes.md b/extensions/Worker.Extensions.Http/release_notes.md index cac20a938..f1bef606f 100644 --- a/extensions/Worker.Extensions.Http/release_notes.md +++ b/extensions/Worker.Extensions.Http/release_notes.md @@ -6,4 +6,4 @@ ### Microsoft.Azure.Functions.Worker.Extensions.Http -- The 'FromBody' converter now utilizes `DeserializeAsync` for deserializing JSON content from the request body, enhancing support for asynchronous deserialization. (#) +- The 'FromBody' converter now utilizes `DeserializeAsync` for deserializing JSON content from the request body, enhancing support for asynchronous deserialization. (#2901)