Voici une autre alternative si, pour une raison quelconque, vous ne pouvez pas ou ne voulez pas utiliser HttpUtility.ParseQueryString().
Ceci est construit pour être quelque peu tolérant aux chaînes de requête "mal formées", c'est-à-dire qu'il http://test/test.html?empty=devient un paramètre avec une valeur vide. L'appelant peut vérifier les paramètres si nécessaire.
public static class UriHelper
{
public static Dictionary<string, string> DecodeQueryParameters(this Uri uri)
{
if (uri == null)
throw new ArgumentNullException("uri");
if (uri.Query.Length == 0)
return new Dictionary<string, string>();
return uri.Query.TrimStart('?')
.Split(new[] { '&', ';' }, StringSplitOptions.RemoveEmptyEntries)
.Select(parameter => parameter.Split(new[] { '=' }, StringSplitOptions.RemoveEmptyEntries))
.GroupBy(parts => parts[0],
parts => parts.Length > 2 ? string.Join("=", parts, 1, parts.Length - 1) : (parts.Length > 1 ? parts[1] : ""))
.ToDictionary(grouping => grouping.Key,
grouping => string.Join(",", grouping));
}
}
Tester
[TestClass]
public class UriHelperTest
{
[TestMethod]
public void DecodeQueryParameters()
{
DecodeQueryParametersTest("http://test/test.html", new Dictionary<string, string>());
DecodeQueryParametersTest("http://test/test.html?", new Dictionary<string, string>());
DecodeQueryParametersTest("http://test/test.html?key=bla/blub.xml", new Dictionary<string, string> { { "key", "bla/blub.xml" } });
DecodeQueryParametersTest("http://test/test.html?eins=1&zwei=2", new Dictionary<string, string> { { "eins", "1" }, { "zwei", "2" } });
DecodeQueryParametersTest("http://test/test.html?empty", new Dictionary<string, string> { { "empty", "" } });
DecodeQueryParametersTest("http://test/test.html?empty=", new Dictionary<string, string> { { "empty", "" } });
DecodeQueryParametersTest("http://test/test.html?key=1&", new Dictionary<string, string> { { "key", "1" } });
DecodeQueryParametersTest("http://test/test.html?key=value?&b=c", new Dictionary<string, string> { { "key", "value?" }, { "b", "c" } });
DecodeQueryParametersTest("http://test/test.html?key=value=what", new Dictionary<string, string> { { "key", "value=what" } });
DecodeQueryParametersTest("http://www.google.com/search?q=energy+edge&rls=com.microsoft:en-au&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1%22",
new Dictionary<string, string>
{
{ "q", "energy+edge" },
{ "rls", "com.microsoft:en-au" },
{ "ie", "UTF-8" },
{ "oe", "UTF-8" },
{ "startIndex", "" },
{ "startPage", "1%22" },
});
DecodeQueryParametersTest("http://test/test.html?key=value;key=anotherValue", new Dictionary<string, string> { { "key", "value,anotherValue" } });
}
private static void DecodeQueryParametersTest(string uri, Dictionary<string, string> expected)
{
Dictionary<string, string> parameters = new Uri(uri).DecodeQueryParameters();
Assert.AreEqual(expected.Count, parameters.Count, "Wrong parameter count. Uri: {0}", uri);
foreach (var key in expected.Keys)
{
Assert.IsTrue(parameters.ContainsKey(key), "Missing parameter key {0}. Uri: {1}", key, uri);
Assert.AreEqual(expected[key], parameters[key], "Wrong parameter value for {0}. Uri: {1}", parameters[key], uri);
}
}
}