Il sera également utile pour les objets imbriqués
public static class HttpQueryStrings
{
public static string ToQueryString<T>(this T @this) where T : class
{
StringBuilder query = @this.ToQueryStringBuilder();
if (query.Length > 0)
query[0] = '?';
return query.ToString();
}
private static StringBuilder ToQueryStringBuilder<T>(this T obj, string prefix = "") where T : class
{
var gatherer = new StringBuilder();
foreach (var p in obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (p.GetValue(obj, new object[0]) != null)
{
var value = p.GetValue(obj, new object[0]);
if (p.PropertyType.IsArray && value.GetType() == typeof(DateTime[]))
foreach (var item in value as DateTime[])
gatherer.Append($"&{prefix}{p.Name}={item.ToString("yyyy-MM-dd")}");
else if (p.PropertyType.IsArray)
foreach (var item in value as Array)
gatherer.Append($"&{prefix}{p.Name}={item}");
else if (p.PropertyType == typeof(string))
gatherer.Append($"&{prefix}{p.Name}={value}");
else if (p.PropertyType == typeof(DateTime) && !value.Equals(Activator.CreateInstance(p.PropertyType))) // is not default
gatherer.Append($"&{prefix}{p.Name}={((DateTime)value).ToString("yyyy-MM-dd")}");
else if (p.PropertyType.IsValueType && !value.Equals(Activator.CreateInstance(p.PropertyType))) // is not default
gatherer.Append($"&{prefix}{p.Name}={value}");
else if (p.PropertyType.IsClass)
gatherer.Append(value.ToQueryStringBuilder($"{prefix}{p.Name}."));
}
}
return gatherer;
}
}
Un exemple d'utilisation de la solution :
string queryString = new
{
date = new DateTime(2020, 1, 1),
myClass = new MyClass
{
FirstName = "john",
LastName = "doe"
},
myArray = new int[] { 1, 2, 3, 4 },
}.ToQueryString();