web-dev-qa-db-fra.com

Obtenir les paramètres d'URL d'une chaîne dans .NET

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.?

213
Beska

Utilisez la méthode statique ParseQueryString de System.Web.HttpUtility classe qui renvoie NameValueCollection.

Uri myUri = new Uri("http://www.example.com?param1=good&param2=bad");
string param1 = HttpUtility.ParseQueryString(myUri.Query).Get("param1");

Consultez la documentation à l'adresse http://msdn.Microsoft.com/en-us/library/ms150046.aspx

448
CZFox

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");
46
Sergej Andrejev

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);
        }
    }
}
29
alsed42

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
  • etc
11
Tom Ritter

@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&param2=bad" )

Ma solution de contournement:

string RawUrl = "http://www.example.com?param1=good&param2=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" );`
10
Mo Gauvin

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");
2
tomsv

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.

2
David

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;
        }
1
Fandango68
HttpContext.Current.Request.QueryString.Get("id");
1
Hallgeir Engen

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();
        } 
0
Ralle12

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");
0
Erhan Demirci

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
        }
0
Indy411