2009-03-18 10 views
167

Ho una stringa in .NET che in realtà è un URL. Voglio un modo semplice per ottenere il valore da un parametro particolare.Ottieni parametri url da una stringa in .NET

Normalmente, vorrei solo usare Request.Params["theThingIWant"], ma questa stringa non è dalla richiesta. Posso creare una nuova voce di Uri in questo modo:

Uri myUri = new Uri(TheStringUrlIWantMyValueFrom); 

posso usare myUri.Query per ottenere la stringa di query ... ma poi mi pare necessario trovare un modo regexy di dividere in su.

Mi manca qualcosa di ovvio, o non c'è un modo per farlo in modo tale da creare una regex di qualche tipo, ecc.?

risposta

361

Usa ParseQueryString metodo statico di System.Web.HttpUtility classe che restituisce NameValueCollection.

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

consultare la documentazione al http://msdn.microsoft.com/en-us/library/ms150046.aspx

+11

Questo non sembra rilevare il primo parametro. ad esempio, l'analisi di "http://www.google.com/search?q=energy+edge&rls=com.microsoft:en-au&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1" non rileva il parametro q –

+0

@ Andrew Confermo. È strano (bug?). Si continua a usare 'HttpUtility.ParseQueryString (myUri.Query) .Get (0)' e si estrarrà il primo parametro. ' –

+0

Qualsiasi strumento .NET per creare un URL di query con parametri? – Shimmy

11

Sembra che dovresti scorrere i valori di myUri.Query e analizzarlo da lì.

string desiredValue; 
foreach(string item in myUri.Query.Split('&')) 
{ 
    string[] parts = item.Replace('?', '').Split('='); 
    if(parts[0] == "desiredKey") 
    { 
     desiredValue = parts[1]; 
     break; 
    } 
} 

Non vorrei usare questo codice senza testarlo su un gruppo di URL malformati comunque. Potrebbe rompersi su alcuni/tutti questi:

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

Usa .NET Reflector per visualizzare il metodo di System.Web.HttpValueCollectionFillFromString. Questo ti dà il codice che ASP.NET sta usando per riempire la collezione Request.QueryString.

34

Questo è probabilmente quello che volete

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

Grazie molto compatto e utile –

9

@Andrew e @CZFox

Ho avuto lo stesso problema e ho trovato la causa per essere tale parametro si è infatti: http://www.example.com?param1 e non param1 che è quello che ci si aspetterebbe.

Rimuovendo tutti i caratteri prima e incluso il punto interrogativo risolve questo problema.Quindi, in sostanza la funzione HttpUtility.ParseQueryString richiede solo un parametro di stringa di query valido contenente solo i caratteri dopo il punto interrogativo come in:

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

mia soluzione:

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

Quando l'URI viene istanziato, viene visualizzato l'errore "URI non valido: il formato dell'URI non può essere determinato." Non penso che questa soluzione funzioni come previsto. –

+0

@PaulMatthews, hai ragione. Al momento di questa soluzione, stavo usando il vecchio .net framework 2.0. Per confermare, la tua dichiarazione, ho copiato e incollato questa soluzione in LINQPad v2 da Joseph Albahara e ho ricevuto lo stesso errore che hai menzionato. –

+0

@PaulMatthews, Per correggere, rimuovere la riga che legge Uri myUri = new Uri (RawUrl); e passa semplicemente RawUrl all'ultima istruzione come in: string param1 = HttpUtility.ParseQueryString (RawUrl) .Get ("param2"); –

2

È possibile utilizzare la seguente soluzione per farlo funzionare con il primo parametro troppo:

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

Ecco un'altra alternativa se, per qualsiasi motivo, non si può o non si desidera utilizzare HttpUtility.ParseQueryString().

Questo è costruito per essere un po 'tollerante alle stringhe di query "malformate", ovvero http://test/test.html?empty= diventa un parametro con un valore vuoto. Il chiamante può verificare i parametri se necessario.

prova

[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

sembra che tu abbia dimenticato che una querystring può contenere valori duplicati (e.g: selezione multipla) – Dementic

+0

Grazie, hai ragione. L'ho cambiato. – alsed42

0

se si vuole ottenere il vostro nel QueryString a pagina predefinito .Default pagina significa l'URL della pagina corrente. si può provare questo codice:

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

come utilizzare questo con una stringa –

1

Oppure, se non si conosce l'URL (in modo da evitare hardcoding, utilizzare l'esempio AbsoluteUri

...

 //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

L'ho usato e funziona perfettamente

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

da una stringa non stringa di query –