2009-03-18 8 views
167

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.Obtenir les paramètres d'URL à partir d'une chaîne dans .NET

Normalement, j'utiliserais simplement Request.Params["theThingIWant"], mais cette chaîne ne provient pas de la requête. Je peux créer un nouveau Uri élément comme si:

Uri myUri = new Uri(TheStringUrlIWantMyValueFrom); 

Je peux utiliser myUri.Query pour obtenir la chaîne de requête ... mais je semble trouver un moyen regexy de la découper. Est-ce que je manque quelque chose d'évident, ou n'y a-t-il pas de manière intégrée de le faire à court de créer une regex, etc?

Répondre

361

Utilisation de la méthode statique ParseQueryString de System.Web.HttpUtility classe qui retourne NameValueCollection.

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

Consultez la documentation à http://msdn.microsoft.com/en-us/library/ms150046.aspx

+11

Cela ne semble pas détecter le premier paramètre. Par exemple, l'analyse "http://www.google.com/search?q=energy+edge&rls=com.microsoft:fr-fr&&=UTF-8&oe=UTF-8&startIndex=&startPage=1" ne détecte pas le paramètre q –

+0

@ Andrew Je confirme. C'est étrange (bug?). Vous pouvez toujours utiliser 'HttpUtility.ParseQueryString (myUri.Query) .Get (0)' et il va extraire le premier paramètre. ' –

+0

Tout outil .NET pour créer une URL de requête paramétrée? – Shimmy

11

On dirait que vous devriez boucler sur les valeurs de myUri.Query et l'analyser à partir de là. Je ne voudrais pas utiliser ce code sans le tester sur un tas d'URL mal formées. Cependant, je ne vais pas utiliser ce code. Il pourrait briser sur certains/tous ces:

  • hello.html?
  • hello.html?valuelesskey
  • hello.html?key=value=hi
  • hello.html?hi=value?&b=c
  • etc
2

Utilisez .NET réflecteur 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.

34

C'est probablement ce que vous voulez

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

Merci très compact et utile –

9

et @CZFox @ Andrew

J'ai eu le même bug et a trouvé la cause d'être ce paramètre on est en fait: http://www.example.com?param1 et non param1 qui est ce que l'on pourrait attendre.

En supprimant tous les caractères avant et y compris le point d'interrogation corrige ce problème.Donc, en substance la fonction HttpUtility.ParseQueryString ne nécessite qu'un paramètre de chaîne de requête valide contenant des caractères seulement après le point d'interrogation comme dans:

HttpUtility.ParseQueryString ("param1=good&param2=bad") 

Ma solution:

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");` 
+0

Lorsque l'URI est instancié, je reçois l'erreur "URI non valide: le format de l'URI n'a pas pu être déterminé." Je ne pense pas que cette solution fonctionne comme prévu. –

+0

@PaulMatthews, vous avez raison. Au moment de cette solution donnée, j'utilisais l'ancien .net framework 2.0. Pour confirmer, votre déclaration, j'ai copié et collé cette solution dans LINQPad v2 par Joseph Albahara et j'ai reçu la même erreur que vous avez mentionnée. –

+0

@PaulMatthews, Pour corriger, supprime la ligne qui lit Uri myUri = new Uri (RawUrl); et passez simplement RawUrl à la dernière instruction comme dans: string param1 = HttpUtility.ParseQueryString (RawUrl) .Get ("param2"); –

2

Vous pouvez utiliser la solution suivante pour que cela fonctionne avec le premier paramètre trop:

var param1 = 
    HttpUtility.ParseQueryString(url.Substring(
     new []{0, url.IndexOf('?')}.Max() 
    )).Get("param1"); 
19

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 "malformées", c'est-à-dire http://test/test.html?empty= devient un paramètre avec une valeur vide. L'appelant peut vérifier les paramètres si nécessaire.

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); 
     } 
    } 
} 
+1

il semble que vous avez oublié qu'une chaîne de requête peut contenir des valeurs en double (e.g: sélection multiple) – Dementic

+0

Merci, vous avez raison. Je l'ai changé. – alsed42

0

si vous voulez en obtenir votre QueryString à la page par défaut .Default la page signifie que votre URL de la page en cours. vous pouvez essayer ce code:

string paramIl = HttpUtility.ParseQueryString(this.ClientQueryString).Get("city"); 
1
HttpContext.Current.Request.QueryString.Get("id"); 
+0

comment l'utiliser avec une chaîne –

1

Ou si vous ne connaissez pas l'URL (afin d'éviter hardcoding, 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; 
     } 
-2

Je l'ai utilisé et il fonctionne parfaitement

<%=Request.QueryString["id"] %> 
+1

à partir d'une chaîne pas de chaîne de requête –

Questions connexes