From 0c2be2f6e51003bb65d49db625bf3e2feab1571a Mon Sep 17 00:00:00 2001 From: Simon S Date: Sat, 5 Oct 2024 02:13:10 -0700 Subject: [PATCH 01/11] #54978 --- .../src/RequestDelegateFactory.cs | 14 +++++- .../test/RequestDelegateFactoryTests.cs | 49 +++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs index 25f2513c7d4e..acf5ff005682 100644 --- a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs +++ b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs @@ -1955,8 +1955,18 @@ private static Expression BindParameterFromExpression( Expression.Convert(Expression.Constant(parameter.DefaultValue), parameter.ParameterType))); } - private static Expression BindParameterFromProperty(ParameterInfo parameter, MemberExpression property, PropertyInfo itemProperty, string key, RequestDelegateFactoryContext factoryContext, string source) => - BindParameterFromValue(parameter, GetValueFromProperty(property, itemProperty, key, GetExpressionType(parameter.ParameterType)), factoryContext, source); + private static Expression BindParameterFromProperty(ParameterInfo parameter, MemberExpression property, PropertyInfo itemProperty, string key, RequestDelegateFactoryContext factoryContext, string source) + { + var expressionType = GetExpressionType(parameter.ParameterType); + var valueExpression = (source == "header" && expressionType == typeof(string[])) + ? Expression.Call( + typeof(ParsingHelpers).GetMethod(nameof(ParsingHelpers.GetHeaderSplit), BindingFlags.Public | BindingFlags.Static, [typeof(IHeaderDictionary), typeof(string)])!, + property, + Expression.Constant(key)) + : GetValueFromProperty(property, itemProperty, key, expressionType); + + return BindParameterFromValue(parameter, valueExpression, factoryContext, source); + } private static Type? GetExpressionType(Type type) => type.IsArray ? typeof(string[]) : diff --git a/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs b/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs index 2afff2e67bd7..083da9bd7aed 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs +++ b/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.cs @@ -3156,6 +3156,55 @@ static void TestAction([AsParameters] ParameterListRequiredNullableStringFromDif Assert.Null(httpContext.Items["RequiredHeaderParam"]); } + private class ParameterListFromHeaderCommaSeparatedValues + { + [FromHeader(Name = "q")] + public required StringValues? BoundToStringValues { get; set; } + + [FromHeader(Name = "q")] + public string? BoundToString { get; set; } + + [FromHeader(Name = "q")] + public string[]? BoundToStringArray { get; set; } + + [FromHeader(Name = "q")] + public int[]? BoundToIntArray { get; set; } + } + + [Theory] + [InlineData("", new string[] { }, new int[] {})] + [InlineData(" ", new string[] { }, new int[] { })] + [InlineData(",", new string[] { }, new int[] { })] + [InlineData("100", new string[] { "100" }, new int[] { 100 })] + [InlineData("1,2", new string[] { "1", "2" }, new int[] { 1, 2 })] + [InlineData("1, 2 , 3", new string[] { "1", "2", "3" }, new int[] { 1, 2, 3 })] + public async Task RequestDelegateFactory_FromHeader_CommaSeparatedValues(string headerValue, string[] expectedStringArray, int[] expectedIntArray) + { + // Arrange + var httpContext = CreateHttpContext(); + httpContext.Request.Headers["q"] = headerValue; + + void TestAction([AsParameters] ParameterListFromHeaderCommaSeparatedValues args) + { + httpContext.Items[nameof(args.BoundToStringValues)] = args.BoundToStringValues; + httpContext.Items[nameof(args.BoundToString)] = args.BoundToString; + httpContext.Items[nameof(args.BoundToStringArray)] = args.BoundToStringArray; + httpContext.Items[nameof(args.BoundToIntArray)] = args.BoundToIntArray; + } + + var factoryResult = RequestDelegateFactory.Create(TestAction); + var requestDelegate = factoryResult.RequestDelegate; + + // Act + await requestDelegate(httpContext); + + // Assert + Assert.Equal(headerValue, httpContext.Items[nameof(ParameterListFromHeaderCommaSeparatedValues.BoundToString)]); + Assert.Equal(new StringValues(headerValue), httpContext.Items[nameof(ParameterListFromHeaderCommaSeparatedValues.BoundToStringValues)]); + Assert.Equal(expectedStringArray, httpContext.Items[nameof(ParameterListFromHeaderCommaSeparatedValues.BoundToStringArray)]); + Assert.Equal(expectedIntArray, httpContext.Items[nameof(ParameterListFromHeaderCommaSeparatedValues.BoundToIntArray)]); + } + #nullable disable private class ParameterListMixedRequiredStringsFromDifferentSources { From 9f1a7fa83c9d901f388336d06fa764636335b137 Mon Sep 17 00:00:00 2001 From: smnsht Date: Sat, 19 Oct 2024 19:46:33 +0300 Subject: [PATCH 02/11] update EndpointParameterEmitter --- .../Emitters/EndpointParameterEmitter.cs | 9 ++++++--- .../CompileTimeCreationTests.cs | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EndpointParameterEmitter.cs b/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EndpointParameterEmitter.cs index e68aeb559e94..1bdbd27677aa 100644 --- a/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EndpointParameterEmitter.cs +++ b/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EndpointParameterEmitter.cs @@ -18,9 +18,12 @@ internal static void EmitQueryOrHeaderParameterPreparation(this EndpointParamete { codeWriter.WriteLine(endpointParameter.EmitParameterDiagnosticComment()); - var assigningCode = endpointParameter.Source is EndpointParameterSource.Header - ? $"httpContext.Request.Headers[\"{endpointParameter.LookupName}\"]" - : $"httpContext.Request.Query[\"{endpointParameter.LookupName}\"]"; + var assigningCode = (endpointParameter.Source, endpointParameter.IsArray) switch + { + (EndpointParameterSource.Header, true) => $"httpContext.Request.Headers.GetCommaSeparatedValues(\"{endpointParameter.LookupName}\")", + (EndpointParameterSource.Header, false) => $"httpContext.Request.Headers[\"{endpointParameter.LookupName}\"]", + _ => $"httpContext.Request.Query[\"{endpointParameter.LookupName}\"]" + }; codeWriter.WriteLine($"var {endpointParameter.EmitAssigningCodeResult()} = {assigningCode};"); // If we are not optional, then at this point we can just assign the string value to the handler argument, diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/CompileTimeCreationTests.cs b/src/Http/Http.Extensions/test/RequestDelegateGenerator/CompileTimeCreationTests.cs index 56601f5f866c..300977f85781 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/CompileTimeCreationTests.cs +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/CompileTimeCreationTests.cs @@ -788,4 +788,23 @@ public async Task RequestDelegatePopulatesFromOptionalFormParameterStringArray() Assert.Equal(["hello", "bye"], (string[])httpContext.Items["message"]); } + + [Theory] + [InlineData("""app.MapGet("/", ([FromHeader(Name = "q")] string[]? arr) => arr);""", "", "[]")] + [InlineData("""app.MapGet("/", ([FromHeader(Name = "q")] string[]? arr) => arr);""", "a,b,c", "[\"a\",\"b\",\"c\"]")] + [InlineData("""app.MapGet("/", ([FromHeader(Name = "q")] int[]? arr) => arr);""", "1,2,3", "[1,2,3]")] + public async Task RequestDelegateGenerator_FromHeader_CommaSeparatedValues(string source, string headerContent, string expectedBody) + { + var (_, compilation) = await RunGeneratorAsync(source); + var endpoints = GetEndpointsFromCompilation(compilation); + + foreach (var endpoint in endpoints) + { + var httpContext = CreateHttpContext(); + httpContext.Request.Headers["q"] = headerContent; + await endpoint.RequestDelegate(httpContext); + + await VerifyResponseBodyAsync(httpContext, expectedBody); + } + } } From 99619bf7642c31aa4ff11742c7365b13393a1518 Mon Sep 17 00:00:00 2001 From: smnsht Date: Sun, 20 Oct 2024 09:03:41 +0300 Subject: [PATCH 03/11] update snapshots --- ...pAction_ExplicitHeader_ComplexTypeArrayParam.generated.txt | 4 ++-- ...tion_ExplicitHeader_NullableStringArrayParam.generated.txt | 4 ++-- .../MapAction_ExplicitHeader_StringArrayParam.generated.txt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_ComplexTypeArrayParam.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_ComplexTypeArrayParam.generated.txt index 3002127aa54c..3a8e7fe8928b 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_ComplexTypeArrayParam.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_ComplexTypeArrayParam.generated.txt @@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Http.Generated { var wasParamCheckFailure = false; // Endpoint Parameter: p (Type = Microsoft.AspNetCore.Http.Generators.Tests.ParsableTodo[], IsOptional = False, IsParsable = True, IsArray = True, Source = Header) - var p_raw = httpContext.Request.Headers["p"]; + var p_raw = httpContext.Request.Headers.GetCommaSeparatedValues("p"); var p_temp = p_raw.ToArray(); global::Microsoft.AspNetCore.Http.Generators.Tests.ParsableTodo[] p_local = new global::Microsoft.AspNetCore.Http.Generators.Tests.ParsableTodo[p_temp.Length]; for (var i = 0; i < p_temp.Length; i++) @@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Http.Generated { var wasParamCheckFailure = false; // Endpoint Parameter: p (Type = Microsoft.AspNetCore.Http.Generators.Tests.ParsableTodo[], IsOptional = False, IsParsable = True, IsArray = True, Source = Header) - var p_raw = httpContext.Request.Headers["p"]; + var p_raw = httpContext.Request.Headers.GetCommaSeparatedValues("p"); var p_temp = p_raw.ToArray(); global::Microsoft.AspNetCore.Http.Generators.Tests.ParsableTodo[] p_local = new global::Microsoft.AspNetCore.Http.Generators.Tests.ParsableTodo[p_temp.Length]; for (var i = 0; i < p_temp.Length; i++) diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_NullableStringArrayParam.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_NullableStringArrayParam.generated.txt index c4463d8d32ac..6365d1485f43 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_NullableStringArrayParam.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_NullableStringArrayParam.generated.txt @@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Http.Generated { var wasParamCheckFailure = false; // Endpoint Parameter: p (Type = string?[], IsOptional = False, IsParsable = False, IsArray = True, Source = Header) - var p_raw = httpContext.Request.Headers["p"]; + var p_raw = httpContext.Request.Headers.GetCommaSeparatedValues("p"); var p_temp = p_raw.ToArray(); string[] p_local = p_temp!; @@ -125,7 +125,7 @@ namespace Microsoft.AspNetCore.Http.Generated { var wasParamCheckFailure = false; // Endpoint Parameter: p (Type = string?[], IsOptional = False, IsParsable = False, IsArray = True, Source = Header) - var p_raw = httpContext.Request.Headers["p"]; + var p_raw = httpContext.Request.Headers.GetCommaSeparatedValues("p"); var p_temp = p_raw.ToArray(); string[] p_local = p_temp!; diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_StringArrayParam.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_StringArrayParam.generated.txt index 040fdfca9d93..66c4504e000b 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_StringArrayParam.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitHeader_StringArrayParam.generated.txt @@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Http.Generated { var wasParamCheckFailure = false; // Endpoint Parameter: p (Type = string[], IsOptional = False, IsParsable = False, IsArray = True, Source = Header) - var p_raw = httpContext.Request.Headers["p"]; + var p_raw = httpContext.Request.Headers.GetCommaSeparatedValues("p"); var p_temp = p_raw.ToArray(); string[] p_local = p_temp!; @@ -125,7 +125,7 @@ namespace Microsoft.AspNetCore.Http.Generated { var wasParamCheckFailure = false; // Endpoint Parameter: p (Type = string[], IsOptional = False, IsParsable = False, IsArray = True, Source = Header) - var p_raw = httpContext.Request.Headers["p"]; + var p_raw = httpContext.Request.Headers.GetCommaSeparatedValues("p"); var p_temp = p_raw.ToArray(); string[] p_local = p_temp!; From ba2d7301b1f7d15d06bffddb1e23d754033b11f9 Mon Sep 17 00:00:00 2001 From: smnsht Date: Wed, 23 Oct 2024 18:47:34 +0300 Subject: [PATCH 04/11] go back 4 commits in googletest --- src/submodules/googletest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/submodules/googletest b/src/submodules/googletest index df1544bcee0c..829c6bbd13ca 160000 --- a/src/submodules/googletest +++ b/src/submodules/googletest @@ -1 +1 @@ -Subproject commit df1544bcee0c7ce35cd5ea0b3eb8cc81855a4140 +Subproject commit 829c6bbd13ca9be012302827a9bb40210384915d From d5222e1608aa5fd6ec70ff50da68b64eb08b395c Mon Sep 17 00:00:00 2001 From: smnsht Date: Wed, 23 Oct 2024 19:02:21 +0300 Subject: [PATCH 05/11] imporove BindParameterFromProperty(...) readability --- src/Http/Http.Extensions/src/RequestDelegateFactory.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs index acf5ff005682..f878dd55e85f 100644 --- a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs +++ b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs @@ -1957,13 +1957,12 @@ private static Expression BindParameterFromExpression( private static Expression BindParameterFromProperty(ParameterInfo parameter, MemberExpression property, PropertyInfo itemProperty, string key, RequestDelegateFactoryContext factoryContext, string source) { - var expressionType = GetExpressionType(parameter.ParameterType); - var valueExpression = (source == "header" && expressionType == typeof(string[])) + var valueExpression = (source == "header" && parameter.ParameterType.IsArray) ? Expression.Call( typeof(ParsingHelpers).GetMethod(nameof(ParsingHelpers.GetHeaderSplit), BindingFlags.Public | BindingFlags.Static, [typeof(IHeaderDictionary), typeof(string)])!, property, Expression.Constant(key)) - : GetValueFromProperty(property, itemProperty, key, expressionType); + : GetValueFromProperty(property, itemProperty, key, GetExpressionType(parameter.ParameterType)); return BindParameterFromValue(parameter, valueExpression, factoryContext, source); } From f890c723af7d6c8d78c92b79761420483bbfbfbe Mon Sep 17 00:00:00 2001 From: smnsht Date: Wed, 23 Oct 2024 19:26:46 +0300 Subject: [PATCH 06/11] get coverage for both compile-time and run-time code gen with a single test case. --- .../CompileTimeCreationTests.cs | 19 ------------------- .../RequestDelegateCreationTests.Arrays.cs | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/CompileTimeCreationTests.cs b/src/Http/Http.Extensions/test/RequestDelegateGenerator/CompileTimeCreationTests.cs index 300977f85781..56601f5f866c 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/CompileTimeCreationTests.cs +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/CompileTimeCreationTests.cs @@ -788,23 +788,4 @@ public async Task RequestDelegatePopulatesFromOptionalFormParameterStringArray() Assert.Equal(["hello", "bye"], (string[])httpContext.Items["message"]); } - - [Theory] - [InlineData("""app.MapGet("/", ([FromHeader(Name = "q")] string[]? arr) => arr);""", "", "[]")] - [InlineData("""app.MapGet("/", ([FromHeader(Name = "q")] string[]? arr) => arr);""", "a,b,c", "[\"a\",\"b\",\"c\"]")] - [InlineData("""app.MapGet("/", ([FromHeader(Name = "q")] int[]? arr) => arr);""", "1,2,3", "[1,2,3]")] - public async Task RequestDelegateGenerator_FromHeader_CommaSeparatedValues(string source, string headerContent, string expectedBody) - { - var (_, compilation) = await RunGeneratorAsync(source); - var endpoints = GetEndpointsFromCompilation(compilation); - - foreach (var endpoint in endpoints) - { - var httpContext = CreateHttpContext(); - httpContext.Request.Headers["q"] = headerContent; - await endpoint.RequestDelegate(httpContext); - - await VerifyResponseBodyAsync(httpContext, expectedBody); - } - } } diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateCreationTests.Arrays.cs b/src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateCreationTests.Arrays.cs index 275cffd93822..e460f9e6ee84 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateCreationTests.Arrays.cs +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateCreationTests.Arrays.cs @@ -775,4 +775,23 @@ public async Task RequestDelegateHandlesArraysFromExplicitQueryStringSource() Assert.Equal(new[] { 4, 5, 6 }, (int[])httpContext.Items["headers"]!); Assert.Equal(new[] { 7, 8, 9 }, (int[])httpContext.Items["form"]!); } + + [Theory] + [InlineData("""app.MapGet("/", ([FromHeader(Name = "q")] string[]? arr) => arr);""", "", "[]")] + [InlineData("""app.MapGet("/", ([FromHeader(Name = "q")] string[]? arr) => arr);""", "a,b,c", "[\"a\",\"b\",\"c\"]")] + [InlineData("""app.MapGet("/", ([FromHeader(Name = "q")] int[]? arr) => arr);""", "1,2,3", "[1,2,3]")] + public async Task MapMethods_Get_With_CommaSeparatedValues_InHeader_ShouldBindToArray(string source, string headerContent, string expectedBody) + { + var (_, compilation) = await RunGeneratorAsync(source); + var endpoints = GetEndpointsFromCompilation(compilation); + + foreach (var endpoint in endpoints) + { + var httpContext = CreateHttpContext(); + httpContext.Request.Headers["q"] = headerContent; + await endpoint.RequestDelegate(httpContext); + + await VerifyResponseBodyAsync(httpContext, expectedBody); + } + } } From b618f3ce213f0d1f4ae1e6e4efaff02cc76ce6e0 Mon Sep 17 00:00:00 2001 From: smnsht Date: Wed, 23 Oct 2024 19:53:00 +0300 Subject: [PATCH 07/11] merging main --- src/submodules/MessagePack-CSharp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/submodules/MessagePack-CSharp b/src/submodules/MessagePack-CSharp index 9aeb12b9bdb0..95119056ee8f 160000 --- a/src/submodules/MessagePack-CSharp +++ b/src/submodules/MessagePack-CSharp @@ -1 +1 @@ -Subproject commit 9aeb12b9bdb024512ffe2e4bddfa2785dca6e39e +Subproject commit 95119056ee8f4da1714b055a4f16893afaa73af7 From a2b37328d05b43f387752a32d2ba4441b0509d39 Mon Sep 17 00:00:00 2001 From: smnsht Date: Sat, 2 Nov 2024 11:23:27 +0200 Subject: [PATCH 08/11] Revert "go back 4 commits in googletest" This reverts commit ba2d7301b1f7d15d06bffddb1e23d754033b11f9. --- src/submodules/googletest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/submodules/googletest b/src/submodules/googletest index 829c6bbd13ca..df1544bcee0c 160000 --- a/src/submodules/googletest +++ b/src/submodules/googletest @@ -1 +1 @@ -Subproject commit 829c6bbd13ca9be012302827a9bb40210384915d +Subproject commit df1544bcee0c7ce35cd5ea0b3eb8cc81855a4140 From a021c08f60ec0f7db1f9925b1563bb9469056e55 Mon Sep 17 00:00:00 2001 From: smnsht Date: Sat, 2 Nov 2024 11:24:48 +0200 Subject: [PATCH 09/11] Revert "merging main" This reverts commit b618f3ce213f0d1f4ae1e6e4efaff02cc76ce6e0. --- src/submodules/MessagePack-CSharp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/submodules/MessagePack-CSharp b/src/submodules/MessagePack-CSharp index 95119056ee8f..9aeb12b9bdb0 160000 --- a/src/submodules/MessagePack-CSharp +++ b/src/submodules/MessagePack-CSharp @@ -1 +1 @@ -Subproject commit 95119056ee8f4da1714b055a4f16893afaa73af7 +Subproject commit 9aeb12b9bdb024512ffe2e4bddfa2785dca6e39e From 99b5052471f17a71620090ff933fb4e2d95b2286 Mon Sep 17 00:00:00 2001 From: smnsht Date: Sun, 3 Nov 2024 09:53:05 +0200 Subject: [PATCH 10/11] empty From 4677be0d5b0ce4e047a6829281d75cfa1b47827e Mon Sep 17 00:00:00 2001 From: smnsht Date: Thu, 27 Feb 2025 09:37:52 +0200 Subject: [PATCH 11/11] add caching for GetHeaderSplit MethodInfo --- src/Http/Http.Extensions/src/RequestDelegateFactory.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs index f878dd55e85f..c0eaa1c56032 100644 --- a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs +++ b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs @@ -52,6 +52,7 @@ public static partial class RequestDelegateFactory private static readonly MethodInfo ExecuteTaskResultOfTMethod = typeof(RequestDelegateFactory).GetMethod(nameof(ExecuteTaskResult), BindingFlags.NonPublic | BindingFlags.Static)!; private static readonly MethodInfo ExecuteValueResultTaskOfTMethod = typeof(RequestDelegateFactory).GetMethod(nameof(ExecuteValueTaskResult), BindingFlags.NonPublic | BindingFlags.Static)!; private static readonly MethodInfo ExecuteAwaitedReturnMethod = typeof(RequestDelegateFactory).GetMethod(nameof(ExecuteAwaitedReturn), BindingFlags.NonPublic | BindingFlags.Static)!; + private static readonly MethodInfo GetHeaderSplitMethod = typeof(ParsingHelpers).GetMethod(nameof(ParsingHelpers.GetHeaderSplit), BindingFlags.Public | BindingFlags.Static, [typeof(IHeaderDictionary), typeof(string)])!; private static readonly MethodInfo GetRequiredServiceMethod = typeof(ServiceProviderServiceExtensions).GetMethod(nameof(ServiceProviderServiceExtensions.GetRequiredService), BindingFlags.Public | BindingFlags.Static, new Type[] { typeof(IServiceProvider) })!; private static readonly MethodInfo GetServiceMethod = typeof(ServiceProviderServiceExtensions).GetMethod(nameof(ServiceProviderServiceExtensions.GetService), BindingFlags.Public | BindingFlags.Static, new Type[] { typeof(IServiceProvider) })!; private static readonly MethodInfo GetRequiredKeyedServiceMethod = typeof(ServiceProviderKeyedServiceExtensions).GetMethod(nameof(ServiceProviderKeyedServiceExtensions.GetRequiredKeyedService), BindingFlags.Public | BindingFlags.Static, new Type[] { typeof(IServiceProvider), typeof(object) })!; @@ -1958,10 +1959,7 @@ private static Expression BindParameterFromExpression( private static Expression BindParameterFromProperty(ParameterInfo parameter, MemberExpression property, PropertyInfo itemProperty, string key, RequestDelegateFactoryContext factoryContext, string source) { var valueExpression = (source == "header" && parameter.ParameterType.IsArray) - ? Expression.Call( - typeof(ParsingHelpers).GetMethod(nameof(ParsingHelpers.GetHeaderSplit), BindingFlags.Public | BindingFlags.Static, [typeof(IHeaderDictionary), typeof(string)])!, - property, - Expression.Constant(key)) + ? Expression.Call(GetHeaderSplitMethod, property, Expression.Constant(key)) : GetValueFromProperty(property, itemProperty, key, GetExpressionType(parameter.ParameterType)); return BindParameterFromValue(parameter, valueExpression, factoryContext, source);