Me gustaría analizar una cadena como p1=6&p2=7&p3=8
en un NameValueCollection
.
¿Cuál es la forma más elegante de hacer esto cuando no tienes acceso al Page.Request
objeto?
Me gustaría analizar una cadena como p1=6&p2=7&p3=8
en un NameValueCollection
.
¿Cuál es la forma más elegante de hacer esto cuando no tienes acceso al Page.Request
objeto?
Respuestas:
Hay una utilidad .NET incorporada 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
sería mi recomendación, excepto que en el caso de que HttpUtility.ParseQueryString("&X=1&X=2&X=3")
el resultado sea ....X=1,2,3...
tener múltiples parámetros del mismo nombre es poco común pero necesario para admitir parámetros de controlador como int [], IEnumerable <int>, etc. (dichos parámetros podrían utilizarse para admitir varias casillas de verificación) consulte "Múltiples ocurrencias de la misma variable de cadena de consulta se consolidan en una entrada" según el sitio de MS . Una versión artesanal del método podría ser su única opción
HttpUtility.ParseQueryString funcionará mientras 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);
}
}
?foo=1&bar
. HttpUtility
lo analizaría como{ key = null, value = "bar" }
Muchas de las respuestas proporcionan ejemplos personalizados debido a la dependencia de la respuesta aceptada en System.Web . Desde el paquete Microsoft.AspNet.WebApi.Client NuGet hay un método UriExtensions.ParseQueryString , 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 desea evitar la dependencia de System.Web y no quiere usar la suya propia, esta es una buena opción.
Quería eliminar la dependencia de System.Web para poder analizar la cadena de consulta de una implementación de ClickOnce, al tiempo que los requisitos previos se limitaban al "Subconjunto de marcos solo para clientes".
Me gustó la respuesta de rp. Agregué algo 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 que la que ya se proporcionaba al trabajar con consultas 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 <Extension()>
agregar eso también para agregar la capacidad a Uri.
Para hacerlo sin System.Web
, sin escribirlo usted mismo, y sin paquetes NuGet adicionales:
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
Si desea evitar la dependencia de System.Web que se requiere para usar HttpUtility.ParseQueryString , puede usar el Uri
método de extensión que se ParseQueryString
encuentra en System.Net.Http
.
Asegúrese de agregar una referencia (si aún no lo ha hecho) a System.Net.Http
su proyecto.
Tenga en cuenta que debe convertir el cuerpo de la respuesta a válido Uri
para que ParseQueryString
(in 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 ] );
}
}
}
Me acabo de dar cuenta de que Web API Client tiene un ParseQueryString
método de extensión que funciona en Uri
ay devuelve un HttpValueCollection
:
var parameters = uri.ParseQueryString();
string foo = parameters["foo"];
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);
Acabo de mezclar esto del código fuente de Mono . Contiene HttpUtility y todas sus dependencias (como IHtmlString, Helpers, HttpEncoder, HttpQSCollection).
Entonces usar HttpUtility.ParseQueryString
.
https://gist.github.com/bjorn-ali-goransson/b04a7c44808bb2de8cca3fc9a3762f9c
Dado que todo el mundo parece estar pegando su solución ... aquí está la mía :-) Necesitaba esto desde una biblioteca de clase sin System.Web
obtener los parámetros de identificación de los hipervínculos almacenados.
Pensé en compartir porque encuentro esta solución más rápida y mejor.
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")
Acceda a Request.QueryString.Keys para una NameValueCollection de todos los parámetros de cadena de consulta.
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
var q = Request.QueryString;
NameValueCollection qscoll = HttpUtility.ParseQueryString(q.ToString());
let search = window.location.search;
console.log(search);
let qString = search.substring(1);
while(qString.indexOf("+") !== -1)
qString = qString.replace("+", "");
let qArray = qString.split("&");
let values = [];
for(let i = 0; i < qArray.length; i++){
let pos = qArray[i].search("=");
let keyVal = qArray[i].substring(0, pos);
let dataVal = qArray[i].substring(pos + 1);
dataVal = decodeURIComponent(dataVal);
values[keyVal] = dataVal;
}
Traduzco a la versión C # de josh-brown en VB
private System.Collections.Specialized.NameValueCollection ParseQueryString(Uri uri)
{
var result = new System.Collections.Specialized.NameValueCollection(4);
var query = uri.Query;
if (!String.IsNullOrEmpty(query))
{
var pairs = query.Substring(1).Split("&".ToCharArray());
foreach (var pair in pairs)
{
var parts = pair.Split("=".ToCharArray(), 2);
var name = System.Uri.UnescapeDataString(parts[0]);
var value = (parts.Length == 1) ? String.Empty : System.Uri.UnescapeDataString(parts[1]);
result.Add(name, value);
}
}
return result;
}
Este es mi código, creo que es muy útil:
public String GetQueryString(string ItemToRemoveOrInsert = null, string InsertValue = null )
{
System.Collections.Specialized.NameValueCollection filtered = new System.Collections.Specialized.NameValueCollection(Request.QueryString);
if (ItemToRemoveOrInsert != null)
{
filtered.Remove(ItemToRemoveOrInsert);
if (!string.IsNullOrWhiteSpace(InsertValue))
{
filtered.Add(ItemToRemoveOrInsert, InsertValue);
}
}
string StrQr = string.Join("&", filtered.AllKeys.Select(key => key + "=" + filtered[key]).ToArray());
if (!string.IsNullOrWhiteSpace(StrQr)){
StrQr="?" + StrQr;
}
return StrQr;
}