Obter parâmetros de url de uma string no .NET

Eu tenho uma string no .net que é realmente uma URL. Eu quero uma maneira fácil de obter o valor de um parâmetro específico.

Normalmente, eu usaria apenas Request.Params["theThingIWant"] , mas essa string não é da solicitação. Eu posso criar um novo item Uri assim:

 Uri myUri = new Uri(TheStringUrlIWantMyValueFrom); 

Eu posso usar myUri.Query para obter a seqüência de consulta … mas, aparentemente, eu tenho que encontrar alguma maneira regular de dividi-la.

Estou faltando alguma coisa óbvia, ou não há nenhuma maneira embutida de fazer isso, de criar um regex de algum tipo, etc?

Use o método ParseQueryString estático da class System.Web.HttpUtility que retorna NameValueCollection .

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

Verifique a documentação em http://msdn.microsoft.com/pt-br/library/ms150046.aspx

Isso é provavelmente o que você quer

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

Aqui está outra alternativa se, por algum motivo, você não puder ou não quiser usar o HttpUtility.ParseQueryString() .

Isso é construído para ser um pouco tolerante com strings de consulta “malformadas”, ou seja, http://test/test.html?empty= se torna um parâmetro com um valor vazio. O chamador pode verificar os parâmetros, se necessário.

 public static class UriHelper { public static Dictionary DecodeQueryParameters(this Uri uri) { if (uri == null) throw new ArgumentNullException("uri"); if (uri.Query.Length == 0) return new Dictionary(); 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)); } } 

Teste

 [TestClass] public class UriHelperTest { [TestMethod] public void DecodeQueryParameters() { DecodeQueryParametersTest("http://test/test.html", new Dictionary()); DecodeQueryParametersTest("http://test/test.html?", new Dictionary()); DecodeQueryParametersTest("http://test/test.html?key=bla/blub.xml", new Dictionary { { "key", "bla/blub.xml" } }); DecodeQueryParametersTest("http://test/test.html?eins=1&zwei=2", new Dictionary { { "eins", "1" }, { "zwei", "2" } }); DecodeQueryParametersTest("http://test/test.html?empty", new Dictionary { { "empty", "" } }); DecodeQueryParametersTest("http://test/test.html?empty=", new Dictionary { { "empty", "" } }); DecodeQueryParametersTest("http://test/test.html?key=1&", new Dictionary { { "key", "1" } }); DecodeQueryParametersTest("http://test/test.html?key=value?&b=c", new Dictionary { { "key", "value?" }, { "b", "c" } }); DecodeQueryParametersTest("http://test/test.html?key=value=what", new Dictionary { { "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 { { "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 { { "key", "value,anotherValue" } }); } private static void DecodeQueryParametersTest(string uri, Dictionary expected) { Dictionary 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); } } } 

Parece que você deve percorrer os valores de myUri.Query e analisá-lo de lá.

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

Eu não usaria esse código sem testá-lo em um monte de URLs malformados no entanto. Pode quebrar em alguns / todos estes:

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

@Andrew e @CZFox

Eu tive o mesmo erro e descobri que a causa é que o parâmetro 1 é de fato: http://www.example.com?param1 e não param1 que é o que se espera.

Remover todos os caracteres antes e incluindo o ponto de interrogação corrige esse problema. Portanto, basicamente, a function HttpUtility.ParseQueryString requer apenas um parâmetro de string de consulta válido contendo apenas caracteres após o ponto de interrogação, como em:

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

Minha solução alternativa:

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

Você pode usar a seguinte solução alternativa para trabalhar com o primeiro parâmetro também:

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

Use o .NET Reflector para exibir o método FillFromString de System.Web.HttpValueCollection . Isso fornece o código que o ASP.NET está usando para preencher a coleção Request.QueryString .

 HttpContext.Current.Request.QueryString.Get("id"); 

Ou se você não souber o URL (para evitar codificação, use o AbsoluteUri

Exemplo …

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

se você quiser obter o seu QueryString na página padrão. Página padrão significa sua url da página atual. você pode tentar este código:

 string paramIl = HttpUtility.ParseQueryString(this.ClientQueryString).Get("city"); 

Eu usei e correu perfeitamente

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