web-development-kb-es.site

Cómo analizar una cadena de consulta en un NameValueCollection en .NET

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?

181
Nathan Smith

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.

345
Guy Starbuck

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);
   }
}
43
Scott Dorman

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.

25
James Skimming

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;
    }
19
densom

Necesitaba una función que sea un poco más versátil de lo que se proporcionaba al trabajar con las consultas de OLSC.

  • Los valores pueden contener múltiples signos iguales
  • Decodifique los caracteres codificados en nombre y valor
  • Capaz de ejecutarse en Client Framework
  • Capaz de ejecutarse en Mobile Framework.

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.

7
Josh Brown

Para hacer esto sin System.Web, sin escribirlo usted mismo y sin paquetes adicionales de NuGet:

  1. Añadir una referencia a System.Net.Http.Formatting
  2. Añadir using System.Net.Http;
  3. Usa este código:

    new Uri(uri).ParseQueryString()
    

https://msdn.Microsoft.com/en-us/library/system.net.http.uriextensions(v=vs.118).aspx

7
jvenema

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"];
2
Thomas Levesque

Si desea evitar la dependencia de System.Web que se requiere para usar HttpUtility.ParseQueryString , puede usar el método de extensión UriParseQueryString 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();
2
Amadeus Sánchez
    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 ] );    
            }    
        }
    }
2
rp.

Sólo tienes que acceder a Request.QueryString. AllKeys mencionado como otra respuesta solo te da una serie de claves.

1
Bloodhound

Si no desea la dependencia de System.Web, simplemente pegue este código fuente de la clase HttpUtility.

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

1
user3638471

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); 
1
alex1kirch

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")
1
Tiele Declercq

Haga clic en Request.QueryString.Keys para obtener un NameValueCollection de todos los parámetros de cadena de consulta.

0
Mark Glorie
        var q = Request.QueryString;
        NameValueCollection qscoll = HttpUtility.ParseQueryString(q.ToString());
0
marven

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
0
mirko cro 1234