En m'inspirant du commentaire de Roy Tinker, j'ai fini par utiliser une méthode d'extension simple sur la classe Uri qui permet de garder un code concis et propre :
using System.Web;
public static class HttpExtensions
{
public static Uri AddQuery(this Uri uri, string name, string value)
{
var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);
httpValueCollection.Remove(name);
httpValueCollection.Add(name, value);
var ub = new UriBuilder(uri);
ub.Query = httpValueCollection.ToString();
return ub.Uri;
}
}
Utilisation :
Uri url = new Uri("http://localhost/rest/something/browse").
AddQuery("page", "0").
AddQuery("pageSize", "200");
Edit - Variante conforme aux normes
Comme plusieurs personnes l'ont souligné, httpValueCollection.ToString()
encode les caractères Unicode dans un non conforme aux normes façon. Il s'agit d'une variante de la même méthode d'extension qui traite de tels caractères en invoquant HttpUtility.UrlEncode
au lieu de la méthode dépréciée HttpUtility.UrlEncodeUnicode
méthode.
using System.Web;
public static Uri AddQuery(this Uri uri, string name, string value)
{
var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);
httpValueCollection.Remove(name);
httpValueCollection.Add(name, value);
var ub = new UriBuilder(uri);
// this code block is taken from httpValueCollection.ToString() method
// and modified so it encodes strings with HttpUtility.UrlEncode
if (httpValueCollection.Count == 0)
ub.Query = String.Empty;
else
{
var sb = new StringBuilder();
for (int i = 0; i < httpValueCollection.Count; i++)
{
string text = httpValueCollection.GetKey(i);
{
text = HttpUtility.UrlEncode(text);
string val = (text != null) ? (text + "=") : string.Empty;
string[] vals = httpValueCollection.GetValues(i);
if (sb.Length > 0)
sb.Append('&');
if (vals == null || vals.Length == 0)
sb.Append(val);
else
{
if (vals.Length == 1)
{
sb.Append(val);
sb.Append(HttpUtility.UrlEncode(vals[0]));
}
else
{
for (int j = 0; j < vals.Length; j++)
{
if (j > 0)
sb.Append('&');
sb.Append(val);
sb.Append(HttpUtility.UrlEncode(vals[j]));
}
}
}
}
}
ub.Query = sb.ToString();
}
return ub.Uri;
}
32 votes
C'est un peu triste que même à l'heure actuelle, il ne semble pas y avoir de simple pour traiter les chaînes de requêtes. Et par simple, j'entends une classe de cadre OOB, non interne, conforme aux normes. Ou peut-être que je passe à côté de quelque chose ?
6 votes
Il ne vous manque rien. La construction de querystring est une lacune majeure dans le cadre de travail que j'ai essayé de combler avec Flurl .
2 votes
Personnellement, la technique que j'utilise est celle que j'ai mentionnée dans cette question :
0 votes
Vous venez de me faire penser que je devrais en construire un new UrlBuilder(existing).AddQuery("key", "value").ToString()
0 votes
Cette réponse fonctionnera également pour les objets facilement imbriqués. Entrez la description du lien ici