From 69920873ea3382b538bf7b85006c63169b8f3f8e Mon Sep 17 00:00:00 2001 From: Safia Abdalla Date: Tue, 20 Aug 2024 09:07:18 -0700 Subject: [PATCH] Add explicit conversion for value-type returning handlers with filters --- .../src/RequestDelegateFactory.cs | 5 + ...estDelegateFactoryTests.EndpointFilters.cs | 98 +++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 src/Http/Http.Extensions/test/RequestDelegateFactoryTests.EndpointFilters.cs diff --git a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs index f30dbe63ca10..159982900eda 100644 --- a/src/Http/Http.Extensions/src/RequestDelegateFactory.cs +++ b/src/Http/Http.Extensions/src/RequestDelegateFactory.cs @@ -543,6 +543,11 @@ private static Expression MapHandlerReturnTypeToValueTask(Expression methodCall, } } + if (returnType.IsValueType) + { + return Expression.Call(WrapObjectAsValueTaskMethod, Expression.Convert(methodCall, typeof(object))); + } + return Expression.Call(WrapObjectAsValueTaskMethod, methodCall); } diff --git a/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.EndpointFilters.cs b/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.EndpointFilters.cs new file mode 100644 index 000000000000..894abb121049 --- /dev/null +++ b/src/Http/Http.Extensions/test/RequestDelegateFactoryTests.EndpointFilters.cs @@ -0,0 +1,98 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.InternalTesting; + +namespace Microsoft.AspNetCore.Routing.Internal; + +public partial class RequestDelegateFactoryTests : LoggedTest +{ + public static object[][] ValueTypeReturningDelegates => + [ + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 'b')], + [(Func)((HttpContext httpContext) => true)], + [(Func)((HttpContext httpContext) => 4.2f)], + [(Func)((HttpContext httpContext) => 4.2)], + [(Func)((HttpContext httpContext) => 4.2m)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)] + ]; + + [Theory] + [MemberData(nameof(ValueTypeReturningDelegates))] + public void Create_WithEndpointFilterOnBuiltInValueTypeReturningDelegate_Works(Delegate @delegate) + { + var invokeCount = 0; + + RequestDelegateFactoryOptions options = new() + { + EndpointBuilder = CreateEndpointBuilderFromFilterFactories( + [ + (routeHandlerContext, next) => + { + invokeCount++; + return next; + }, + (routeHandlerContext, next) => + { + invokeCount++; + return next; + }, + ]), + }; + + var result = RequestDelegateFactory.Create(@delegate, options); + Assert.Equal(2, invokeCount); + } + + public static object[][] NullableValueTypeReturningDelegates => + [ + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 'b')], + [(Func)((HttpContext httpContext) => true)], + [(Func)((HttpContext httpContext) => 4.2f)], + [(Func)((HttpContext httpContext) => 4.2)], + [(Func)((HttpContext httpContext) => 4.2m)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)], + [(Func)((HttpContext httpContext) => 42)] + ]; + + [Theory] + [MemberData(nameof(NullableValueTypeReturningDelegates))] + public void Create_WithEndpointFilterOnNullableBuiltInValueTypeReturningDelegate_Works(Delegate @delegate) + { + var invokeCount = 0; + + RequestDelegateFactoryOptions options = new() + { + EndpointBuilder = CreateEndpointBuilderFromFilterFactories( + [ + (routeHandlerContext, next) => + { + invokeCount++; + return next; + }, + (routeHandlerContext, next) => + { + invokeCount++; + return next; + }, + ]), + }; + + var result = RequestDelegateFactory.Create(@delegate, options); + Assert.Equal(2, invokeCount); + } +}