J'ai une chaîne dans .NET qui est en fait une URL. Je veux un moyen facile d'obtenir la valeur d'un paramètre particulier.
Normalement, je n'utiliserais que Request.Params["theThingIWant"]
, mais cette chaîne ne fait pas partie de la requête. Je peux créer un nouvel élément Uri
comme suit:
Uri myUri = new Uri(TheStringUrlIWantMyValueFrom);
Je peux utiliser myUri.Query
pour obtenir la chaîne de requête ... mais il me semble alors que je dois trouver un moyen de fractionner la regexy.
Est-ce que je manque quelque chose d'évident, ou n'y a-t-il pas de manière structurée de le faire si ce n'est de créer une regex quelconque, etc.?
Utilisez la méthode statique ParseQueryString
de System.Web.HttpUtility
classe qui renvoie NameValueCollection
.
Uri myUri = new Uri("http://www.example.com?param1=good¶m2=bad");
string param1 = HttpUtility.ParseQueryString(myUri.Query).Get("param1");
Consultez la documentation à l'adresse http://msdn.Microsoft.com/en-us/library/ms150046.aspx
C'est probablement ce que tu veux
var uri = new Uri("http://domain.test/Default.aspx?var1=true&var2=test&var3=3");
var query = HttpUtility.ParseQueryString(uri.Query);
var var2 = query.Get("var2");
Voici une autre alternative si, pour une raison quelconque, vous ne pouvez pas ou ne voulez pas utiliser HttpUtility.ParseQueryString()
.
Ceci est conçu pour être quelque peu tolérant envers les chaînes de requête "mal formées", c'est-à-dire que 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));
}
}
Test
[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);
}
}
}
On dirait que vous devriez parcourir les valeurs de myUri.Query
et les analyser à partir de là.
string desiredValue;
foreach(string item in myUri.Query.Split('&'))
{
string[] parts = item.Replace('?', '').Split('=');
if(parts[0] == "desiredKey")
{
desiredValue = parts[1];
break;
}
}
Cependant, je n'utiliserais pas ce code sans le tester sur plusieurs URL malformées. Cela pourrait casser sur certains/tous ceux-ci:
hello.html?
hello.html?valuelesskey
hello.html?key=value=hi
hello.html?hi=value?&b=c
@Andrew et @CZFox
J'avais le même bogue et j'ai trouvé que la cause de ce paramètre était en fait: http://www.example.com?param1
et non pas param1
, ce à quoi on pourrait s'attendre.
En supprimant tous les caractères avant et y compris le point d'interrogation résout ce problème. Donc, essentiellement, la fonction HttpUtility.ParseQueryString
requiert uniquement un paramètre de chaîne de requête valide contenant uniquement des caractères après le point d'interrogation, comme dans:
HttpUtility.ParseQueryString ( "param1=good¶m2=bad" )
Ma solution de contournement:
string RawUrl = "http://www.example.com?param1=good¶m2=bad";
int index = RawUrl.IndexOf ( "?" );
if ( index > 0 )
RawUrl = RawUrl.Substring ( index ).Remove ( 0, 1 );
Uri myUri = new Uri( RawUrl, UriKind.RelativeOrAbsolute);
string param1 = HttpUtility.ParseQueryString( myUri.Query ).Get( "param1" );`
Vous pouvez utiliser la solution de contournement suivante pour qu'il fonctionne également avec le premier paramètre:
var param1 =
HttpUtility.ParseQueryString(url.Substring(
new []{0, url.IndexOf('?')}.Max()
)).Get("param1");
Utilisez .NET Reflector pour afficher la méthode FillFromString
de System.Web.HttpValueCollection
. Cela vous donne le code utilisé par ASP.NET pour remplir la collection Request.QueryString
.
Ou si vous ne connaissez pas l’URL (pour éviter le codage en dur, utilisez le AbsoluteUri
Exemple ...
//get the full URL
Uri myUri = new Uri(Request.Url.AbsoluteUri);
//get any parameters
string strStatus = HttpUtility.ParseQueryString(myUri.Query).Get("status");
string strMsg = HttpUtility.ParseQueryString(myUri.Query).Get("message");
switch (strStatus.ToUpper())
{
case "OK":
webMessageBox.Show("EMAILS SENT!");
break;
case "ER":
webMessageBox.Show("EMAILS SENT, BUT ... " + strMsg);
break;
}
HttpContext.Current.Request.QueryString.Get("id");
C'est en fait très simple, et cela a fonctionné pour moi :)
if (id == "DK")
{
string longurl = "selectServer.aspx?country=";
var uriBuilder = new UriBuilder(longurl);
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
query["country"] = "DK";
uriBuilder.Query = query.ToString();
longurl = uriBuilder.ToString();
}
si vous voulez en obtenir votre QueryString sur la page par défaut. La page par défaut signifie l'URL de votre page actuelle. vous pouvez essayer ce code:
string paramIl = HttpUtility.ParseQueryString(this.ClientQueryString).Get("city");
Pour tous ceux qui souhaitent parcourir toutes les chaînes de requête d'une chaîne
foreach (var item in new Uri(urlString).Query.TrimStart('?').Split('&'))
{
var subStrings = item.Split('=');
var key = subStrings[0];
var value = subStrings[1];
// do something with values
}