Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Add a TreatAsString field to QueryAttribute #1943

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions Refit.Tests/RequestBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2044,6 +2044,7 @@ Task QueryWithOptionalParameters(
int id,
[Query] string text = null,
[Query] int? optionalId = null,
[Query(TreatAsString = true)] Foo foo = null,
[Query(CollectionFormat = CollectionFormat.Multi)] string[] filters = null
);

Expand Down Expand Up @@ -3541,12 +3542,12 @@ string expectedQuery
}

[Theory]
[InlineData("/api/123?text=title&optionalId=999&filters=A&filters=B")]
[InlineData("/api/123?text=title&optionalId=999&foo=foo&filters=A&filters=B")]
public void TestNullableQueryStringParams(string expectedQuery)
{
var fixture = new RequestBuilderImplementation<IDummyHttpApi>();
var factory = fixture.BuildRequestFactoryForMethod("QueryWithOptionalParameters");
var output = factory(new object[] { 123, "title", 999, new string[] { "A", "B" } });
var output = factory(new object[] { 123, "title", 999, new Foo(), new string[] { "A", "B" } });

var uri = new Uri(new Uri("http://api"), output.RequestUri);
Assert.Equal(expectedQuery, uri.PathAndQuery);
Expand All @@ -3558,7 +3559,7 @@ public void TestNullableQueryStringParamsWithANull(string expectedQuery)
{
var fixture = new RequestBuilderImplementation<IDummyHttpApi>();
var factory = fixture.BuildRequestFactoryForMethod("QueryWithOptionalParameters");
var output = factory(new object[] { 123, "title", null, new string[] { "A", "B" } });
var output = factory(new object[] { 123, "title", null, null, new string[] { "A", "B" } });

var uri = new Uri(new Uri("http://api"), output.RequestUri);
Assert.Equal(expectedQuery, uri.PathAndQuery);
Expand Down Expand Up @@ -3944,6 +3945,14 @@ public void ComplexQueryObjectWithDictionaryAndCustomFormatterProducesCorrectQue
}
}

public record Foo
{
public override string ToString()
{
return "foo";
}
}

static class RequestBuilderTestExtensions
{
public static Func<object[], HttpRequestMessage> BuildRequestFactoryForMethod(
Expand Down
6 changes: 6 additions & 0 deletions Refit/Attributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,12 @@ public QueryAttribute(CollectionFormat collectionFormat)
CollectionFormat = collectionFormat;
}

/// <summary>
/// Used to specify that the value should be treated as a string.
/// Set to true if you want to call ToString() on the object before adding it to the query string.
/// </summary>
public bool TreatAsString { get; set; }

/// <summary>
/// Used to customize the name of either the query parameter pair or of the form field when form encoding.
/// </summary>
Expand Down
13 changes: 12 additions & 1 deletion Refit/RequestBuilderImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -946,7 +946,18 @@ void AddQueryParameters(RestMethodInfoInternal restMethod, QueryAttribute? query
List<KeyValuePair<string, string?>> queryParamsToAdd, int i, RestMethodParameterInfo? parameterInfo)
{
var attr = queryAttribute ?? DefaultQueryAttribute;
if (DoNotConvertToQueryMap(param))
if (attr.TreatAsString)
{
queryParamsToAdd.AddRange(
ParseQueryParameter(
param.ToString(),
restMethod.ParameterInfoArray[i],
restMethod.QueryParameterMap[i],
attr
)
);
}
else if (DoNotConvertToQueryMap(param))
{
queryParamsToAdd.AddRange(
ParseQueryParameter(
Expand Down
Loading