Skip to content

Commit 16d146f

Browse files
committed
Support IEnumerable<KeyValuePair<TKey,TValue>> serialize key=value
1 parent 1a4f8d8 commit 16d146f

File tree

5 files changed

+78
-13
lines changed

5 files changed

+78
-13
lines changed

sandbox/ConsoleApp/Program.cs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,25 @@
11
using Cysharp.Web;
22
using System.Net.Http.Json;
3+
using System.Runtime.InteropServices;
34
using System.Runtime.Serialization;
45
using System.Text;
56
using System.Text.Encodings.Web;
67
using System.Web;
78

8-
var httpClient = new HttpClient { BaseAddress = new Uri("http://localhost:5000") };
9-
//var api = RestService.For<IMinimumAPI>(client);
10-
//await api.Get(10, "octocat");
9+
var parameters = new KeyValuePair<string, string>[]
10+
{
11+
new ("id", "1"),
12+
new ("name", "tanaka"),
13+
new ("email", "[email protected]")
14+
};
15+
16+
Console.WriteLine(WebSerializer.ToQueryString("https://example.com/user", parameters));
17+
1118

12-
//var k = " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
13-
//var s1 = UrlEncoder.Default.Encode(k);
14-
//var s2 = HttpUtility.UrlEncode(k);
15-
//Console.WriteLine(s1);
16-
//Console.WriteLine(s2);
17-
//return;
1819

1920

20-
//await httpClient.GetAsync(WebSerializer.ToQueryString("Products", new { foo = new[] { 1, 10, 1000 } }, WebSerializerOptions.Default with { CollectionSeparator = "," }));
21+
//GCHandle handle = GCHandle.Alloc("", GCHandleType.Pinned);
2122

22-
var s = WebSerializer.ToQueryString("http://www.example.com/q?foo=bar", new { hoge = "moge" });
23-
Console.WriteLine(s);
2423

2524
return;
2625

sandbox/WebApp/Program.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
builder.Logging.ClearProviders();
77
builder.Logging.AddZLoggerConsole();
88

9+
10+
11+
912
builder.Services.AddControllers();
1013

1114
var app = builder.Build();

src/WebSerializer/Providers/CollectionWebSerializerProvider.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,16 @@ public sealed class CollectionWebSerializerProvider : IWebSerializerProvider
3636
if (enumerableDef != null)
3737
{
3838
var elementType = enumerableDef.GenericTypeArguments[0];
39-
return CreateInstance(typeof(EnumerableWebSerializer<,>), new[] { type, elementType });
39+
if (elementType.IsGenericType && elementType.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
40+
{
41+
var keyType = elementType.GenericTypeArguments[0];
42+
var valueType = elementType.GenericTypeArguments[1];
43+
return CreateInstance(typeof(EnumerableKeyValuePairWebSerializer<,,>), new[] { type, keyType, valueType });
44+
}
45+
else
46+
{
47+
return CreateInstance(typeof(EnumerableWebSerializer<,>), new[] { type, elementType });
48+
}
4049
}
4150
}
4251

src/WebSerializer/Serializers/CollectionSerializers.cs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,46 @@ public void Serialize(ref WebSerializerWriter writer, TDictionary value, WebSeri
8282
valueSerializer.Serialize(ref writer, item.Value, options);
8383
}
8484

85+
writer.Exit();
86+
}
87+
}
88+
89+
public sealed class EnumerableKeyValuePairWebSerializer<TCollection, TKey, TValue> : IWebSerializer<TCollection>
90+
where TCollection : IEnumerable<KeyValuePair<TKey, TValue>>
91+
{
92+
public void Serialize(ref WebSerializerWriter writer, TCollection value, WebSerializerOptions options)
93+
{
94+
if (value == null) return;
95+
96+
writer.EnterAndValidate(options);
97+
98+
var keySerializer = options.GetRequiredSerializer<TKey>();
99+
var valueSerializer = options.GetRequiredSerializer<TValue>();
100+
101+
var first = true;
102+
foreach (var item in value)
103+
{
104+
if (item.Value == null) continue;
105+
106+
if (first)
107+
{
108+
first = false;
109+
}
110+
else
111+
{
112+
writer.AppendConcatenate();
113+
}
114+
115+
// Name
116+
writer.AppendNamePrefix();
117+
keySerializer.Serialize(ref writer, item.Key, options);
118+
119+
writer.AppendEqual();
120+
121+
// Value
122+
valueSerializer.Serialize(ref writer, item.Value, options);
123+
}
124+
85125
writer.Exit();
86126
}
87127
}

tests/WebSerializer.Tests/CollectionTest.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ public void Dict()
4949
WebSerializer.ToQueryString(foo, newConfig).Should().Be("Yeah=100&Kuooo=nano%20yo&DEAR=0");
5050
}
5151

52+
[Fact]
53+
public void KVP()
54+
{
55+
var parameters = new KeyValuePair<string, string>[]
56+
{
57+
new ("id", "1"),
58+
new ("name", "tanaka"),
59+
new ("email", "[email protected]")
60+
};
61+
62+
var url = WebSerializer.ToQueryString("https://example.com/user", parameters);
63+
64+
url.Should().Be("https://example.com/user?id=1&name=tanaka&email=test%40example.com");
65+
}
5266

5367
public class BoolZeroOneSerializer : IWebSerializer<bool>
5468
{

0 commit comments

Comments
 (0)