it-swarm-fr.com

Comment analyser une chaîne de requête dans une NameValueCollection dans .NET

Je voudrais analyser une chaîne telle que p1=6&p2=7&p3=8 dans un NameValueCollection.

Quel est le moyen le plus élégant de le faire quand vous n’avez pas accès à la Page.Request objet?

181
Nathan Smith

Il existe un utilitaire .NET intégré pour cela: HttpUtility.ParseQueryString

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

Vous devrez peut-être remplacer querystring par new Uri(fullUrl).Query.

348
Guy Starbuck

HttpUtility.ParseQueryString fonctionnera aussi longtemps que vous serez dans une application Web ou n’importe où, y compris une dépendance à System.Web. Une autre façon de faire est:

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

Un grand nombre de réponses fournissent des exemples personnalisés en raison de la dépendance de la réponse acceptée sur System.Web . Le package Microsoft.AspNet.WebApi.Client NuGet contient une méthode riExtensions.ParseQueryString , qui peut également être utilisée:

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

Donc, si vous voulez éviter la dépendance System.Web et que vous ne voulez pas avoir la vôtre, c'est une bonne option.

25
James Skimming

Je souhaitais supprimer la dépendance sur System.Web afin d'analyser la chaîne de requête d'un déploiement ClickOnce, tout en limitant les conditions préalables au "sous-ensemble de structure client uniquement".

J'ai aimé la réponse de RP. J'ai ajouté une logique supplémentaire.

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

J'avais besoin d'une fonction un peu plus polyvalente que celle fournie lors de l'utilisation de requêtes OLSC.

  • Les valeurs peuvent contenir plusieurs signes égaux
  • Décoder les caractères encodés en nom et en valeur
  • Capable de fonctionner sur Client Framework
  • Capable de fonctionner sur Mobile Framework.

Voici ma solution:

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

Ce n’est peut-être pas une mauvaise idée d’ajouter <Extension()> à cela aussi pour ajouter la capacité à Uri lui-même.

7
Josh Brown

Faire ceci sans System.Web, sans écrire vous-même, et sans paquets NuGet supplémentaires:

  1. Ajouter une référence à System.Net.Http.Formatting
  2. Ajouter using System.Net.Http;
  3. Utilisez ce code:

    new Uri(uri).ParseQueryString()
    

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

7
jvenema

Je viens de me rendre compte que Web API Client a une méthode d'extension ParseQueryString qui fonctionne sur un Uri et renvoie un HttpValueCollection:

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

Si vous voulez éviter la dépendance à System.Web qui est nécessaire pour utiliser HttpUtility.ParseQueryString , vous pouvez utiliser la méthode d'extension UriParseQueryString trouvée dans System.Net.Http.

Assurez-vous d’ajouter une référence (si ce n’est déjà fait) à System.Net.Http dans votre projet.

Notez que vous devez convertir le corps de la réponse en un Uri valide pour que ParseQueryString (dans System.Net.Http)travaux.

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.

Il suffit d’accéder à Request.QueryString. AllKeys mentionné comme une autre réponse vous donne juste un tableau de clés.

1
Bloodhound

Si vous ne voulez pas la dépendance System.Web, collez simplement ce code source à partir de la classe HttpUtility.

Je viens de fouetter ceci ensemble à partir du code source de Mono . Il contient le HttpUtility et toutes ses dépendances (comme IHtmlString, Helpers, HttpEncoder, HttpQSCollection).

Puis utilisez HttpUtility.ParseQueryString.

https://Gist.github.com/bjorn-ALi-goransson/b04a7c44808bb2de8cca3fc9a3762f9c

1
user3638471

HttpUtility.ParseQueryString(Request.Url.Query) return is HttpValueCollection (classe interne). Il hérite 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

Puisque tout le monde semble coller sa solution ... voici la mienne :-) J'avais besoin de ça depuis une bibliothèque de classe sans System.Web pour récupérer les paramètres id des hyperliens stockés.

Je pensais partager parce que je trouve cette solution plus rapide et plus esthétique.

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

Usage:

Statics.QueryGet(url, "id")
1
Tiele Declercq

Accédez à Request.QueryString.Keys pour une NameValueCollection de tous les paramètres de chaîne de requête.

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

Pour obtenir toutes les valeurs Querystring, essayez ceci:

    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