diff --git a/src/Refit/RequestBuilderImplementation.cs b/src/Refit/RequestBuilderImplementation.cs index 65b8757c6..1ce011fad 100644 --- a/src/Refit/RequestBuilderImplementation.cs +++ b/src/Refit/RequestBuilderImplementation.cs @@ -352,9 +352,16 @@ private RestMethodInfoInternal FindMatchingRestMethodInfo( foreach (var method in possibleMethods) { - if (ParametersMatch(method.MethodInfo.GetParameters(), parameterTypes)) + try + { + var closedMethod = CloseGenericMethodIfNeeded(method, genericArgumentTypes); + if (ParametersMatch(closedMethod.MethodInfo.GetParameters(), parameterTypes)) + { + return closedMethod; + } + } + catch (Exception exception) when (exception.Message.Contains("violates the constraint", StringComparison.CurrentCultureIgnoreCase)) { - return CloseGenericMethodIfNeeded(method, genericArgumentTypes); } } diff --git a/src/tests/Refit.Tests/ReflectionTests.cs b/src/tests/Refit.Tests/ReflectionTests.cs index 4b832bc00..da186ab0a 100644 --- a/src/tests/Refit.Tests/ReflectionTests.cs +++ b/src/tests/Refit.Tests/ReflectionTests.cs @@ -68,19 +68,20 @@ public interface IGenericMethodAndInterface /// Request with a generic route parameter and additional parameter. /// Generic route parameter. /// Integer route parameter. - /// Generic type of route parameter. + /// Generic type of route parameter, constrained to value types. /// A task that completes when the request finishes. [Get("/{value1}/{value2}")] - Task GetGenericParameter(T1 value1, int value2); + Task GetGenericParameter(T1 value1, int value2) + where T1 : struct; - // This should be renamed to GetGenericParameter once #2197 is fixed. /// Request with two generic route parameters. /// First generic route parameter. /// Second generic route parameter. - /// Generic type of first route parameter. + /// Generic type of first route parameter, constrained to reference types. /// A task that completes when the request finishes. [Get("/{value1}/{value2}")] - Task GetClassGenericParameter(T1 value1, TInterface value2); + Task GetGenericParameter(T1 value1, TInterface value2) + where T1 : class; } /// Verifies a simple string path parameter is formatted with the expected metadata. @@ -517,21 +518,21 @@ public async Task GenericOverloadedInterfaceWithTwoGenericParameterShouldBeExpec { { Route.Get("https://foo/10/Empty"), - Reply.Json(nameof(IGenericMethodAndInterface<>.GetClassGenericParameter)) + Reply.Json(nameof(IGenericMethodAndInterface<>.GetGenericParameter)) }, }; var methodInfo = typeof(IGenericMethodAndInterface).GetMethod( - nameof(IGenericMethodAndInterface<>.GetClassGenericParameter), + nameof(IGenericMethodAndInterface<>.GetGenericParameter), 1, [Type.MakeGenericMethodParameter(0), typeof(string)])!; - methodInfo = methodInfo.MakeGenericMethod(typeof(long)); + methodInfo = methodInfo.MakeGenericMethod(typeof(string)); var parameterInfo1 = methodInfo.GetParameters()[0]; var parameterInfo2 = methodInfo.GetParameters()[1]; var formatter = new TestUrlFormatter( [parameterInfo1, parameterInfo2], - [typeof(long), typeof(string)]); + [typeof(string), typeof(string)]); var settings = new RefitSettings { HttpMessageHandlerFactory = () => handler, @@ -539,7 +540,7 @@ public async Task GenericOverloadedInterfaceWithTwoGenericParameterShouldBeExpec }; var service = RestService.For>(BaseUrl, settings); - await service.GetClassGenericParameter(LongValue, "Empty"); + await service.GetGenericParameter("10", "Empty"); await formatter.AssertNoOutstandingAssertions(); } }