Me gustaría analizar una cadena como p1=6&p2=7&p3=8
en una NameValueCollection
.
¿Cuál es la forma más elegante de hacerlo cuando no tiene acceso al objeto Page.Request
?
Hay una utilidad incorporada .NET para esto: HttpUtility.ParseQueryString
// C#
NameValueCollection qscoll = HttpUtility.ParseQueryString(querystring);
' VB.NET
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)
Es posible que deba reemplazar querystring
con new Uri(fullUrl).Query
.
HttpUtility.ParseQueryString funcionará siempre que esté en una aplicación web o no le importe incluir una dependencia en System.Web. Otra forma de hacer esto es:
NameValueCollection queryParameters = new NameValueCollection();
string[] querySegments = queryString.Split('&');
foreach(string segment in querySegments)
{
string[] parts = segment.Split('=');
if (parts.Length > 0)
{
string key = parts[0].Trim(new char[] { '?', ' ' });
string val = parts[1].Trim();
queryParameters.Add(key, val);
}
}
Muchas de las respuestas proporcionan ejemplos personalizados debido a la dependencia de la respuesta aceptada en System.Web . Del método Microsoft.AspNet.WebApi.Client NuGet hay un UriExtensions.ParseQueryString , método que también se puede usar:
var uri = new Uri("https://stackoverflow.com/a/22167748?p1=6&p2=7&p3=8");
NameValueCollection query = uri.ParseQueryString();
Entonces, si quiere evitar la dependencia de System.Web y no quiere rodar la suya, esta es una buena opción.
Quería eliminar la dependencia en System.Web para poder analizar la cadena de consulta de una implementación de ClickOnce, mientras que los requisitos previos se limitan al "subconjunto de marco solo para clientes".
Me gustó la respuesta de rp. Agregué un poco de lógica adicional.
public static NameValueCollection ParseQueryString(string s)
{
NameValueCollection nvc = new NameValueCollection();
// remove anything other than query string from url
if(s.Contains("?"))
{
s = s.Substring(s.IndexOf('?') + 1);
}
foreach (string vp in Regex.Split(s, "&"))
{
string[] singlePair = Regex.Split(vp, "=");
if (singlePair.Length == 2)
{
nvc.Add(singlePair[0], singlePair[1]);
}
else
{
// only one key with no value specified in query string
nvc.Add(singlePair[0], string.Empty);
}
}
return nvc;
}
Necesitaba una función que sea un poco más versátil de lo que se proporcionaba al trabajar con las consultas de OLSC.
Aquí está mi solución:
Public Shared Function ParseQueryString(ByVal uri As Uri) As System.Collections.Specialized.NameValueCollection
Dim result = New System.Collections.Specialized.NameValueCollection(4)
Dim query = uri.Query
If Not String.IsNullOrEmpty(query) Then
Dim pairs = query.Substring(1).Split("&"c)
For Each pair In pairs
Dim parts = pair.Split({"="c}, 2)
Dim name = System.Uri.UnescapeDataString(parts(0))
Dim value = If(parts.Length = 1, String.Empty,
System.Uri.UnescapeDataString(parts(1)))
result.Add(name, value)
Next
End If
Return result
End Function
Puede que no sea una mala idea incluir <Extension()>
en eso también para agregar la capacidad a Uri.
Para hacer esto sin System.Web
, sin escribirlo usted mismo y sin paquetes adicionales de NuGet:
System.Net.Http.Formatting
using System.Net.Http;
Usa este código:
new Uri(uri).ParseQueryString()
https://msdn.Microsoft.com/en-us/library/system.net.http.uriextensions(v=vs.118).aspx
Acabo de darme cuenta de que Web API Client tiene un método de extensión ParseQueryString
que funciona en una Uri
y devuelve una HttpValueCollection
:
var parameters = uri.ParseQueryString();
string foo = parameters["foo"];
Si desea evitar la dependencia de System.Web que se requiere para usar HttpUtility.ParseQueryString , puede usar el método de extensión Uri
ParseQueryString
que se encuentra en System.Net.Http
.
Asegúrese de agregar una referencia (si aún no lo ha hecho) a System.Net.Http
en su proyecto.
Tenga en cuenta que debe convertir el cuerpo de la respuesta en un Uri
válido para que ParseQueryString
(en System.Net.Http
) funcione.
string body = "value1=randomvalue1&value2=randomValue2";
// "http://localhost/query?" is added to the string "body" in order to create a valid Uri.
string urlBody = "http://localhost/query?" + body;
NameValueCollection coll = new Uri(urlBody).ParseQueryString();
private void button1_Click( object sender, EventArgs e )
{
string s = @"p1=6&p2=7&p3=8";
NameValueCollection nvc = new NameValueCollection();
foreach ( string vp in Regex.Split( s, "&" ) )
{
string[] singlePair = Regex.Split( vp, "=" );
if ( singlePair.Length == 2 )
{
nvc.Add( singlePair[ 0 ], singlePair[ 1 ] );
}
}
}
Sólo tienes que acceder a Request.QueryString. AllKeys mencionado como otra respuesta solo te da una serie de claves.
Acabo de batir esto juntos desde el código fuente de Mono . Contiene el HttpUtility y todas sus dependencias (como IHtmlString, Helpers, HttpEncoder, HttpQSCollection).
Entonces use HttpUtility.ParseQueryString
.
https://Gist.github.com/bjorn-ALi-goransson/b04a7c44808bb2de8cca3fc9a3762f9c
HttpUtility.ParseQueryString(Request.Url.Query)
return es HttpValueCollection
(clase interna). Hereda de NameValueCollection
.
var qs = HttpUtility.ParseQueryString(Request.Url.Query);
qs.Remove("foo");
string url = "~/Default.aspx";
if (qs.Count > 0)
url = url + "?" + qs.ToString();
Response.Redirect(url);
Dado que todos parecen estar pegando su solución ... aquí está la mía :-) Necesitaba esto desde una biblioteca de clase sin System.Web
para obtener parámetros de identificación de los hipervínculos almacenados.
Pensé que compartiría porque encuentro esta solución más rápida y mejor parecida.
public static class Statics
public static Dictionary<string, string> QueryParse(string url)
{
Dictionary<string, string> qDict = new Dictionary<string, string>();
foreach (string qPair in url.Substring(url.IndexOf('?') + 1).Split('&'))
{
string[] qVal = qPair.Split('=');
qDict.Add(qVal[0], Uri.UnescapeDataString(qVal[1]));
}
return qDict;
}
public static string QueryGet(string url, string param)
{
var qDict = QueryParse(url);
return qDict[param];
}
}
Uso:
Statics.QueryGet(url, "id")
Haga clic en Request.QueryString.Keys para obtener un NameValueCollection de todos los parámetros de cadena de consulta.
var q = Request.QueryString;
NameValueCollection qscoll = HttpUtility.ParseQueryString(q.ToString());
Para obtener todos los valores de Querystring intente esto:
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)
Dim sb As New StringBuilder("<br />")
For Each s As String In qscoll.AllKeys
Response.Write(s & " - " & qscoll(s) & "<br />")
Next s