Obtenga los parámetros url de una cadena en .NET

Tengo una cadena en .NET que en realidad es una url. Quiero una manera fácil de obtener el valor de un parámetro en particular.

Normalmente, solo usaría Request.Params["theThingIWant"] , pero esta cadena no es de la solicitud. Puedo crear un nuevo elemento de Uri como ese:

 Uri myUri = new Uri(TheStringUrlIWantMyValueFrom); 

Puedo usar myUri.Query para obtener la cadena de consulta … pero luego, aparentemente, tengo que buscar alguna forma gemela de dividirla.

¿Me estoy perdiendo algo obvio, o no hay una forma construida para hacer esto sin crear una expresión regular de algún tipo, etc.?

Utilice el método estático ParseQueryString de la clase System.Web.HttpUtility que devuelve NameValueCollection .

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

Consulte la documentación en http://msdn.microsoft.com/en-us/library/ms150046.aspx

Esto es probablemente lo que quieres

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

Aquí hay otra alternativa si, por alguna razón, no puede o no quiere usar HttpUtility.ParseQueryString() .

Esto está diseñado para ser algo tolerante con las cadenas de consulta “malformadas”, es decir, http://test/test.html?empty= convierte en un parámetro con un valor vacío. El que llama puede verificar los parámetros si es necesario.

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

Prueba

 [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 deberías recorrer los valores de myUri.Query y analizarlos desde allí.

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

Sin embargo, no usaría este código sin probarlo en un montón de URL mal formadas. Puede romper con algunos / todos estos:

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

@Andrew y @CZFox

Tuve el mismo error y encontré que la causa es que el parámetro uno es de hecho: http://www.example.com?param1 y no param1 que es lo que uno esperaría.

Al eliminar todos los caracteres antes e incluir el signo de interrogación corrige este problema. Así que, en esencia, la función HttpUtility.ParseQueryString solo requiere un parámetro de cadena de consulta válida que contenga solo caracteres después del signo de interrogación como en:

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

Mi solución:

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

Puede usar la siguiente solución temporal para que funcione también con el primer parámetro:

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

Utilice .NET Reflector para ver el método FillFromString de System.Web.HttpValueCollection . Eso le proporciona el código que ASP.NET está utilizando para completar la colección Request.QueryString .

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

O si no conoce la URL (para evitar la encoding rígida, use AbsoluteUri

Ejemplo …

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

si lo desea, obtenga su QueryString en la página predeterminada. La página predeterminada significa su url de página actual. puedes probar este código:

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

Lo usé y funciona perfectamente

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