Domanda

Vorrei analizzare una stringa come p1=6&p2=7&p3=8 in un NameValueCollection.

Che cosa è il modo più elegante per farlo quando non hai accesso al Page.Request oggetto?

È stato utile?

Soluzione

C'è un built-in .NET utilità per questo: HttpUtility.ParseQueryString

// C#
NameValueCollection qscoll = HttpUtility.ParseQueryString(querystring);
' VB.NET
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)

Potrebbe essere necessario sostituire querystring con new Uri(fullUrl).Query.

Altri suggerimenti

HttpUtility.ParseQueryString funzionerà fino a quando si è in una web app o non mente, compresi una dipendenza di Sistema.Web.Un altro modo per fare questo è:

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

Un sacco di risposte stanno fornendo esempi personalizzati a causa della accettati risposta dipendenza Sistema.Web.Dal Microsoft.AspNet.WebApi.Client Pacchetto NuGet c'è un UriExtensions.ParseQueryString, metodo che può essere utilizzato anche:

var uri = new Uri("https://stackoverflow.com/a/22167748?p1=6&p2=7&p3=8");
NameValueCollection query = uri.ParseQueryString();

Quindi, se si vuole evitare il Sistema.Web dipendenza e non voglio rotolare il vostro proprio, questa è una buona opzione.

Ho voluto rimuovere la dipendenza del Sistema.Web in modo che io possa analizzare la stringa di query di una distribuzione ClickOnce, pur avendo i prerequisiti limitato al "solo Client Framework Sottoinsieme".

Mi è piaciuto rp risposta.Ho aggiunto qualche altra logica.

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

Ho bisogno di una funzione che è un po ' più versatile rispetto a quello che era già previsto quando si lavora con OLSC query.

  • I valori possono contenere più segni di uguale
  • Decodificare i caratteri codificati in nome e valore
  • In grado di eseguire sul Client Framework
  • In grado di funzionare su Framework Mobile.

Ecco la mia soluzione:

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

Potrebbe non essere una cattiva idea per virare <Extension()> anche su questo per aggiungere la capacità di Uri stesso.

Per fare questo senza System.Web, senza scrivere voi stessi, e senza ulteriori pacchetti NuGet:

  1. Aggiungere un riferimento a System.Net.Http.Formatting
  2. Aggiungere using System.Net.Http;
  3. Uso questo codice:

    new Uri(uri).ParseQueryString()
    

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

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

Ho appena realizzato che Web API Client ha un ParseQueryString estensione del metodo che funziona su una Uri e restituisce un HttpValueCollection:

var parameters = uri.ParseQueryString();
string foo = parameters["foo"];

Se si desidera evitare la dipendenza del Sistema.Web che è necessario per utilizzare HttpUtility.ParseQueryString, si potrebbe utilizzare il Uri metodo di estensione ParseQueryString trovato in System.Net.Http.

Assicurarsi di aggiungere un riferimento (se non l'hai già fatto) per System.Net.Http nel progetto.

Si noti che è necessario convertire la risposta del corpo ad una valida Uri in modo che ParseQueryString (in System.Net.Http)funziona.

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

Solo la Richiesta di accesso.QueryString.AllKeys menzionato come un altro di risposta appena si ottiene una matrice di tasti.

HttpUtility.ParseQueryString(Request.Url.Query) il ritorno è HttpValueCollection (classe interna).Eredita da 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); 

Se non si desidera che il Sistema.Web dipendenza, basta incollare questo codice sorgente da HttpUtility classe.

Ho appena montata insieme dal codice sorgente di Mono.Esso contiene i HttpUtility e tutte le sue dipendenze (come IHtmlString, Aiutanti, HttpEncoder, HttpQSCollection).

Quindi utilizzare HttpUtility.ParseQueryString.

https://gist.github.com/bjorn-ali-goransson/b04a7c44808bb2de8cca3fc9a3762f9c

Dal momento che tutti sembrano essere incollando la sua soluzione..ecco la mia :-) Ho bisogno di questo da all'interno di una libreria di classi senza System.Web per recuperare l'id parametri memorizzati i collegamenti ipertestuali.

Ho pensato di condividere perché trovo questa soluzione più veloce e migliore.

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

Utilizzo:

Statics.QueryGet(url, "id")

Hit su Richiesta.QueryString.Le chiavi per un NameValueCollection di tutti i parametri della stringa di query.

Per ottenere tutti i valori Querystring provare questo:

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

Traduco per C# versione di josh marrone-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;
}

Questo è il mio codice, penso che sarebbe molto utile:

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top