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¶m2=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
@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¶m2=bad" )
Mi solución:
string RawUrl = "http://www.example.com?param1=good¶m2=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"] %>