From b6071c08cab1d1f2812e13d39b5a79b6ca02c32c Mon Sep 17 00:00:00 2001 From: Timothy Makkison Date: Fri, 8 Nov 2024 20:28:03 +0000 Subject: [PATCH] fix: support nullable value type collection in queries --- Refit.Tests/RestService.cs | 21 +++++++++++++++++++++ Refit/RequestBuilderImplementation.cs | 13 ++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/Refit.Tests/RestService.cs b/Refit.Tests/RestService.cs index 0d7c13c6e..e7b4a792d 100644 --- a/Refit.Tests/RestService.cs +++ b/Refit.Tests/RestService.cs @@ -298,6 +298,9 @@ public interface IQueryApi [Get("/foo?{key}={value}")] Task ParameterMappedQuery(string key, string value); + + [Get("/foo")] + Task NullableIntCollectionQuery([Query] int?[] values); } public interface IFragmentApi @@ -2456,6 +2459,24 @@ public async Task ParameterMappedQueryShouldEscape() mockHttp.VerifyNoOutstandingExpectation(); } + [Fact] + public async Task NullableIntCollectionQuery() + { + var mockHttp = new MockHttpMessageHandler(); + var settings = new RefitSettings { HttpMessageHandlerFactory = () => mockHttp, }; + + mockHttp + .Expect(HttpMethod.Get, "https://github.com/foo") + .WithExactQueryString("values=3%2C4%2C") + .Respond(HttpStatusCode.OK); + + var fixture = RestService.For("https://github.com", settings); + + await fixture.NullableIntCollectionQuery([3, 4, null]); + + mockHttp.VerifyNoOutstandingExpectation(); + } + [Fact] public async Task ShouldStripFragment() { diff --git a/Refit/RequestBuilderImplementation.cs b/Refit/RequestBuilderImplementation.cs index f2c2662a0..eec31a9f9 100644 --- a/Refit/RequestBuilderImplementation.cs +++ b/Refit/RequestBuilderImplementation.cs @@ -1349,12 +1349,15 @@ static bool DoNotConvertToQueryMap(object? value) type = intType.GetGenericArguments()[0]; return ShouldReturn(type); + // Check if type is a simple string or IFormattable type, check underlying type if Nullable static bool ShouldReturn(Type type) => - type == typeof(string) - || type == typeof(bool) - || type == typeof(char) - || typeof(IFormattable).IsAssignableFrom(type) - || type == typeof(Uri); + Nullable.GetUnderlyingType(type) is { } underlyingType + ? ShouldReturn(underlyingType) + : type == typeof(string) + || type == typeof(bool) + || type == typeof(char) + || typeof(IFormattable).IsAssignableFrom(type) + || type == typeof(Uri); } static void SetHeader(HttpRequestMessage request, string name, string? value)