Skip to content

Commit 46e6ff9

Browse files
committed
Fixed misc issues with parsing query strings with comma separated values
1 parent 7489bb0 commit 46e6ff9

3 files changed

Lines changed: 246 additions & 7 deletions

File tree

src/Skybrud.Essentials.AspNetCore/QueryStringExtensions.cs

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ public static bool TryGetInt32(this IQueryCollection query, string key, [NotNull
108108
}
109109

110110
/// <summary>
111-
/// Returns an <see cref="int"/> array based on the values of each query string component with the specified
112-
/// <paramref name="key"/>.
111+
/// Returns an <see cref="int"/> array based on the values of each query string component with the specified <paramref name="key"/>.
113112
/// </summary>
114113
/// <param name="query">The query string.</param>
115114
/// <param name="key">The key of the query string components.</param>
@@ -121,6 +120,19 @@ public static int[] GetInt32Array(this IQueryCollection? query, string key) {
121120
return query == null ? Array.Empty<int>() : query[key].ToInt32Array();
122121
}
123122

123+
/// <summary>
124+
/// Returns an <see cref="int"/> array based on the values of each query string component with the specified <paramref name="key"/>.
125+
/// </summary>
126+
/// <param name="query">The query string.</param>
127+
/// <param name="key">The key of the query string components.</param>
128+
/// <returns>An <see cref="int"/> list representing the converted values.</returns>
129+
/// <remarks>The value of each query string component may themselves be a separated list of <see cref="int"/>
130+
/// values - eg. separated by commas. Values that can not be converted to a corresponding <see cref="int"/>
131+
/// value will be ignored.</remarks>
132+
public static List<int> GetInt32List(this IQueryCollection? query, string key) {
133+
return query?[key].ToInt32List() ?? new List<int>();
134+
}
135+
124136
/// <summary>
125137
/// Gets the value of the first query string component with the specified <paramref name="key"/>, and returns
126138
/// the value as a <see cref="long"/>. If a matching query string component isn't found, or the value could not
@@ -171,8 +183,7 @@ public static bool TryGetInt64(this IQueryCollection query, string key, [NotNull
171183
}
172184

173185
/// <summary>
174-
/// Returns a <see cref="long"/> array based on the values of each query string component with the specified
175-
/// <paramref name="key"/>.
186+
/// Returns a <see cref="long"/> array based of the values of each query string component with the specified <paramref name="key"/>.
176187
/// </summary>
177188
/// <param name="query">The query string.</param>
178189
/// <param name="key">The key of the query string components.</param>
@@ -184,6 +195,19 @@ public static long[] GetInt64Array(this IQueryCollection? query, string key) {
184195
return query == null ? Array.Empty<long>() : query[key].ToInt64Array();
185196
}
186197

198+
/// <summary>
199+
/// Returns a <see cref="long"/> list based of the values of each query string component with the specified <paramref name="key"/>.
200+
/// </summary>
201+
/// <param name="query">The query string.</param>
202+
/// <param name="key">The key of the query string components.</param>
203+
/// <returns>A <see cref="long"/> list representing the converted values.</returns>
204+
/// <remarks>The value of each query string component may themselves be a separated list of <see cref="long"/>
205+
/// values - eg. separated by commas. Values that can not be converted to a corresponding <see cref="long"/>
206+
/// value will be ignored.</remarks>
207+
public static List<long> GetInt64List(this IQueryCollection? query, string key) {
208+
return query?[key].ToInt64List() ?? new List<long>();
209+
}
210+
187211
/// <summary>
188212
/// Gets the value of the first query string component with the specified <paramref name="key"/>, and returns
189213
/// the value as a <see cref="float"/>. If a matching query string component isn't found, or the value could
@@ -234,8 +258,7 @@ public static bool TryGetFloat(this IQueryCollection query, string key, [NotNull
234258
}
235259

236260
/// <summary>
237-
/// Returns a <see cref="float"/> array based on the values of each query string component with the specified
238-
/// <paramref name="key"/>.
261+
/// Returns a <see cref="float"/> array based on the values of each query string component with the specified <paramref name="key"/>.
239262
/// </summary>
240263
/// <param name="query">The query string.</param>
241264
/// <param name="key">The key of the query string components.</param>
@@ -244,7 +267,20 @@ public static bool TryGetFloat(this IQueryCollection query, string key, [NotNull
244267
/// values - eg. separated by commas. Values that can not be converted to a corresponding <see cref="float"/>
245268
/// value will be ignored.</remarks>
246269
public static float[] GetFloatArray(this IQueryCollection? query, string key) {
247-
return query == null ? Array.Empty<float>() : query[key].ToFloatArray();
270+
return query?[key].ToFloatArray() ?? Array.Empty<float>();
271+
}
272+
273+
/// <summary>
274+
/// Returns a <see cref="float"/> list based on the values of each query string component with the specified <paramref name="key"/>.
275+
/// </summary>
276+
/// <param name="query">The query string.</param>
277+
/// <param name="key">The key of the query string components.</param>
278+
/// <returns>A <see cref="float"/> list representing the converted values.</returns>
279+
/// <remarks>The value of each query string component may themselves be a separated list of <see cref="float"/>
280+
/// values - eg. separated by commas. Values that can not be converted to a corresponding <see cref="float"/>
281+
/// value will be ignored.</remarks>
282+
public static List<float> GetFloatList(this IQueryCollection? query, string key) {
283+
return query?[key].ToFloatList() ?? new List<float>();
248284
}
249285

250286
/// <summary>
@@ -309,6 +345,19 @@ public static double[] GetDoubleArray(this IQueryCollection? query, string key)
309345
return query == null ? Array.Empty<double>() : query[key].ToDoubleArray();
310346
}
311347

348+
/// <summary>
349+
/// Returns a <see cref="double"/> list based on the values of each query string component with the specified <paramref name="key"/>.
350+
/// </summary>
351+
/// <param name="query">The query string.</param>
352+
/// <param name="key">The key of the query string components.</param>
353+
/// <returns>A <see cref="double"/> list representing the converted values.</returns>
354+
/// <remarks>The value of each query string component may themselves be a separated list of <see cref="double"/>
355+
/// values - eg. separated by commas. Values that can not be converted to a corresponding <see cref="double"/>
356+
/// value will be ignored.</remarks>
357+
public static List<double> GetDoubleList(this IQueryCollection? query, string key) {
358+
return query?[key].ToDoubleList() ?? new List<double>();
359+
}
360+
312361
/// <summary>
313362
/// Gets the value of the first query string component with the specified <paramref name="key"/>, and returns
314363
/// the value as a <see cref="bool"/>. If a matching query string component isn't found, or the value could not

src/Skybrud.Essentials.AspNetCore/StringValuesExtensions.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using Microsoft.Extensions.Primitives;
34
using Skybrud.Essentials.Strings.Extensions;
45
using System.Linq;
@@ -42,6 +43,15 @@ public static int[] ToInt32Array(this StringValues values) {
4243
return values.SelectMany(StringUtils.ParseInt32Array).ToArray();
4344
}
4445

46+
/// <summary>
47+
/// Parses the specified array of string <paramref name="values"/> into an <see cref="int"/> list.
48+
/// </summary>
49+
/// <param name="values">The string values.</param>
50+
/// <returns>A list of <see cref="int"/>.</returns>
51+
public static List<int> ToInt32List(this StringValues values) {
52+
return values.SelectMany(StringUtils.ParseInt32List).ToList();
53+
}
54+
4555
/// <summary>
4656
/// Converts the specified <paramref name="values" /> to a <see cref="long" /> value.
4757
/// </summary>
@@ -73,6 +83,15 @@ public static long[] ToInt64Array(this StringValues values) {
7383
return values.SelectMany(StringUtils.ParseInt64Array).ToArray();
7484
}
7585

86+
/// <summary>
87+
/// Parses the specified array of string <paramref name="values"/> into a <see cref="long"/> list.
88+
/// </summary>
89+
/// <param name="values">The string values.</param>
90+
/// <returns>A list of <see cref="long"/>.</returns>
91+
public static List<long> ToInt64List(this StringValues values) {
92+
return values.SelectMany(StringUtils.ParseInt64List).ToList();
93+
}
94+
7695
/// <summary>
7796
/// Converts the specified <paramref name="values" /> to a <see cref="float" /> value.
7897
/// </summary>
@@ -104,6 +123,15 @@ public static float[] ToFloatArray(this StringValues values) {
104123
return values.SelectMany(StringUtils.ParseFloatArray).ToArray();
105124
}
106125

126+
/// <summary>
127+
/// Parses the specified array of string <paramref name="values"/> into a <see cref="float"/> list.
128+
/// </summary>
129+
/// <param name="values">The string values.</param>
130+
/// <returns>A list of <see cref="float"/>.</returns>
131+
public static List<float> ToFloatList(this StringValues values) {
132+
return values.SelectMany(StringUtils.ParseFloatList).ToList();
133+
}
134+
107135
/// <summary>
108136
/// Converts the specified <paramref name="values" /> to a <see cref="double" /> value.
109137
/// </summary>
@@ -135,6 +163,15 @@ public static double[] ToDoubleArray(this StringValues values) {
135163
return values.SelectMany(StringUtils.ParseDoubleArray).ToArray();
136164
}
137165

166+
/// <summary>
167+
/// Parses the specified array of string <paramref name="values"/> into a <see cref="double"/> list.
168+
/// </summary>
169+
/// <param name="values">The string values.</param>
170+
/// <returns>A list of <see cref="double"/>.</returns>
171+
public static List<double> ToDoubleList(this StringValues values) {
172+
return values.SelectMany(StringUtils.ParseDoubleList).ToList();
173+
}
174+
138175
/// <summary>
139176
/// Converts the specified <paramref name="values" /> to a <see cref="bool" /> value. If the conversion fails,
140177
/// <c>false</c> is returned instead.

src/TestProject1/QueryStringTests.cs

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Globalization;
12
using Microsoft.AspNetCore.Http;
23
using Microsoft.AspNetCore.WebUtilities;
34
using Microsoft.Extensions.Primitives;
@@ -8,6 +9,158 @@ namespace TestProject1 {
89
[TestClass]
910
public class QueryStringTests {
1011

12+
#region Int32
13+
14+
[TestMethod]
15+
public void GetInt32Array() {
16+
17+
IQueryCollection query = new QueryCollection(new Dictionary<string, StringValues> {
18+
{"ints", new StringValues(new[] { "1,2", "3", "nope", null })}
19+
});
20+
21+
var array = query.GetInt32Array("ints");
22+
23+
Assert.AreEqual(3, array.Length);
24+
25+
Assert.AreEqual(1, array[0]);
26+
Assert.AreEqual(2, array[1]);
27+
Assert.AreEqual(3, array[2]);
28+
29+
}
30+
31+
[TestMethod]
32+
public void GetInt32List() {
33+
34+
IQueryCollection query = new QueryCollection(new Dictionary<string, StringValues> {
35+
{"ints", new StringValues(new[] { "1,2", "3", "nope", null })}
36+
});
37+
38+
var array = query.GetInt32List("ints");
39+
40+
Assert.AreEqual(3, array.Count);
41+
42+
Assert.AreEqual(1, array[0]);
43+
Assert.AreEqual(2, array[1]);
44+
Assert.AreEqual(3, array[2]);
45+
46+
}
47+
48+
#endregion
49+
50+
#region Int64
51+
52+
[TestMethod]
53+
public void GetInt64Array() {
54+
55+
IQueryCollection query = new QueryCollection(new Dictionary<string, StringValues> {
56+
{"longs", new StringValues(new[] { "1,2", "3", "nope", null })}
57+
});
58+
59+
var array = query.GetInt64Array("longs");
60+
61+
Assert.AreEqual(3, array.Length);
62+
63+
Assert.AreEqual(1, array[0]);
64+
Assert.AreEqual(2, array[1]);
65+
Assert.AreEqual(3, array[2]);
66+
67+
}
68+
69+
[TestMethod]
70+
public void GetInt64List() {
71+
72+
IQueryCollection query = new QueryCollection(new Dictionary<string, StringValues> {
73+
{"longs", new StringValues(new[] { "1,2", "3", "nope", null })}
74+
});
75+
76+
var array = query.GetInt64List("longs");
77+
78+
Assert.AreEqual(3, array.Count);
79+
80+
Assert.AreEqual(1, array[0]);
81+
Assert.AreEqual(2, array[1]);
82+
Assert.AreEqual(3, array[2]);
83+
84+
}
85+
86+
#endregion
87+
88+
#region Float / Single
89+
90+
[TestMethod]
91+
public void GetFloatArray() {
92+
93+
IQueryCollection query = new QueryCollection(new Dictionary<string, StringValues> {
94+
{"floats", new StringValues(new[] { "1,2", "3.4", "nope", null })}
95+
});
96+
97+
var array = query.GetFloatArray("floats");
98+
99+
Assert.AreEqual(3, array.Length);
100+
101+
Assert.AreEqual(1, array[0]);
102+
Assert.AreEqual(2, array[1]);
103+
Assert.AreEqual("3.4", array[2].ToString("N1", CultureInfo.InvariantCulture));
104+
105+
}
106+
107+
[TestMethod]
108+
public void GetFLoatList() {
109+
110+
IQueryCollection query = new QueryCollection(new Dictionary<string, StringValues> {
111+
{"floats", new StringValues(new[] { "1,2", "3.4", "nope", null })}
112+
});
113+
114+
var array = query.GetFloatList("floats");
115+
116+
Assert.AreEqual(3, array.Count);
117+
118+
Assert.AreEqual(1, array[0]);
119+
Assert.AreEqual(2, array[1]);
120+
Assert.AreEqual("3.4", array[2].ToString("N1", CultureInfo.InvariantCulture));
121+
122+
}
123+
124+
#endregion
125+
126+
#region Double
127+
128+
[TestMethod]
129+
public void GetDoubleArray() {
130+
131+
IQueryCollection query = new QueryCollection(new Dictionary<string, StringValues> {
132+
{"doubles", new StringValues(new[] { "1,2", "3.4", "nope", null })}
133+
});
134+
135+
var array = query.GetDoubleArray("doubles");
136+
137+
Assert.AreEqual(3, array.Length);
138+
139+
Assert.AreEqual(1, array[0]);
140+
Assert.AreEqual(2, array[1]);
141+
Assert.AreEqual("3.4", array[2].ToString("N1", CultureInfo.InvariantCulture));
142+
143+
}
144+
145+
[TestMethod]
146+
public void GetDoubleList() {
147+
148+
IQueryCollection query = new QueryCollection(new Dictionary<string, StringValues> {
149+
{"doubles", new StringValues(new[] { "1,2", "3.4", "nope", null })}
150+
});
151+
152+
var array = query.GetDoubleList("doubles");
153+
154+
Assert.AreEqual(3, array.Count);
155+
156+
Assert.AreEqual(1, array[0]);
157+
Assert.AreEqual(2, array[1]);
158+
Assert.AreEqual("3.4", array[2].ToString("N1", CultureInfo.InvariantCulture));
159+
160+
}
161+
162+
#endregion
163+
11164
#region Guids
12165

13166
[TestMethod]

0 commit comments

Comments
 (0)