Skip to content

Commit c54181d

Browse files
feat(util): add QueryStringOptions.WithCollectionKeyFormatter to be able to format keys only e.g. convert php like by appending [] to the key (#82)
1 parent ce1c1df commit c54181d

7 files changed

+54
-13
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
[_vNext_](https://github.com/sketch7/FluentlyHttpClient/compare/3.8.1...3.9.0) (2020-X-X)
44

5+
## [3.9.6](https://github.com/sketch7/FluentlyHttpClient/compare/3.9.5...3.9.6) (2024-06-11)
6+
7+
### Features
8+
9+
- **util:** add `QueryStringOptions.WithCollectionKeyFormatter` to be able to format keys only e.g. convert php like by appending `[]` to the key
10+
511
## [3.9.5](https://github.com/sketch7/FluentlyHttpClient/compare/3.9.4...3.9.5) (2024-03-22)
612

713
### Features

Directory.Packages.props

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616

1717
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.3" />
1818

19-
<PackageVersion Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
19+
<PackageVersion Include="Microsoft.AspNet.WebApi.Client" Version="6.0.0" />
2020
<!-- 3rd party -->
2121
<PackageVersion Include="BenchmarkDotNet" Version="0.13.12" />
2222
<PackageVersion Include="MessagePack" Version="2.5.108" />
2323
<PackageVersion Include="MimeTypesMap" Version="1.0.8" />
24-
<PackageVersion Include="Newtonsoft.Json" Version="12.0.1" />
24+
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
2525
<PackageVersion Include="Humanizer.Core" Version="2.7.9" />
2626
<PackageVersion Include="Sketch7.Core" Version="0.1.1" />
2727
<!-- testing -->

NuGet.Config

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<configuration>
3-
<packageSources>
4-
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
5-
</packageSources>
6-
</configuration>
3+
<packageSources>
4+
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
5+
</packageSources>
6+
<packageSourceMapping>
7+
<packageSource key="nuget.org">
8+
<package pattern="*" />
9+
</packageSource>
10+
</packageSourceMapping>
11+
</configuration>

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sketch7/fluently-http-client",
3-
"version": "3.9.5",
3+
"version": "3.9.6",
44
"versionSuffix": "",
55
"scripts": {
66
"pack": "bash ./tools/pack.sh",

src/FluentlyHttpClient/Utils/QueryStringOptions.cs

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.Net;
21
using System.Web;
32

43
#pragma warning disable 618 // todo: remove after removing deprecated code
@@ -41,9 +40,6 @@ public class QueryStringOptions
4140
/// </summary>
4241
public static readonly Func<string, string> DefaultValueEncoder = HttpEncode;
4342

44-
/// <summary>
45-
/// Debugger display.
46-
/// </summary>
4743
protected string DebuggerDisplay => $"CollectionMode: '{CollectionMode}'";
4844

4945
/// <summary>
@@ -65,7 +61,9 @@ public class QueryStringOptions
6561

6662
internal Func<object, string>? ValueFormatter { get; set; }
6763

68-
internal Func<string, string>? ValueEncoder { get; set; } = DefaultValueEncoder;
64+
internal Func<string, string> ValueEncoder { get; set; } = DefaultValueEncoder;
65+
66+
internal Func<string, string>? CollectionKeyFormatter { get; set; }
6967

7068
/// <summary>
7169
/// Gets or sets the function to format a collection item. This will allow you to manipulate the value.
@@ -86,6 +84,16 @@ public QueryStringOptions WithKeyFormatter(Func<string, string> configure)
8684
return this;
8785
}
8886

87+
/// <summary>
88+
/// Gets or sets the function to format the key to be used only for collections. Useful to make php like keys e.g. append '[]' 'filter[]'.
89+
/// NOTE: <see cref="WithKeyFormatter"/> will still be used.
90+
/// </summary>
91+
public QueryStringOptions WithCollectionKeyFormatter(Func<string, string> configure)
92+
{
93+
CollectionKeyFormatter = configure;
94+
return this;
95+
}
96+
8997
/// <summary>
9098
/// Gets or sets the function to format a value. This will allow you to manipulate the value e.g. use enums attribute instead of value.
9199
/// </summary>

src/FluentlyHttpClient/Utils/QueryStringUtils.cs

+4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ public static string ToQueryString<TKey, TValue>(this IDictionary<TKey, TValue>
7474

7575
private static string BuildCollectionQueryString(string key, IEnumerable values, string qs, QueryStringOptions options)
7676
{
77+
key = options.CollectionKeyFormatter == null
78+
? key
79+
: options.CollectionKeyFormatter(key);
80+
7781
switch (options.CollectionMode)
7882
{
7983
case QueryStringCollectionMode.KeyPerValue:

test/Utils/QueryStringUtilsTest.cs

+19-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void ShouldGenerateComplexQueryStringWithoutCollection()
4747
[Fact]
4848
public void ShouldOmitEmptyOrNulls()
4949
{
50-
var queryCollection = new Dictionary<string, object>
50+
var queryCollection = new Dictionary<string, object?>
5151
{
5252
{"heroName", ""},
5353
{"cap", null},
@@ -147,6 +147,24 @@ public void ShouldFormatKeyToLower()
147147
Assert.Equal("heroname=yasuo&level=100", result);
148148
}
149149

150+
[Fact]
151+
public void ShouldFormatCollectionKey()
152+
{
153+
var queryCollection = new Dictionary<string, object>
154+
{
155+
{"HeroName", "yasuo"},
156+
{"filter", new List<string>{ "assassin", "fighter" }}
157+
};
158+
159+
var result = queryCollection.ToQueryString(opts =>
160+
{
161+
opts.CollectionMode = QueryStringCollectionMode.KeyPerValue;
162+
opts.WithCollectionKeyFormatter(key => $"{key}[]");
163+
}
164+
);
165+
166+
Assert.Equal("heroName=yasuo&filter[]=assassin&filter[]=fighter", result);
167+
}
150168

151169
[Fact]
152170
public void ShouldNotHttpEncodeValue()

0 commit comments

Comments
 (0)