Je voudrais analyser une chaîne comme p1=6&p2=7&p3=8
dans un fichier NameValueCollection
.
Quelle est la manière la plus élégante de faire cela lorsque vous n'avez pas accès à l' Page.Request
objet?
Je voudrais analyser une chaîne comme p1=6&p2=7&p3=8
dans un fichier NameValueCollection
.
Quelle est la manière la plus élégante de faire cela lorsque vous n'avez pas accès à l' Page.Request
objet?
Réponses:
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
.
HttpUtility.ParseQueryString
serait ma recommandation sauf que dans le cas du HttpUtility.ParseQueryString("&X=1&X=2&X=3")
résultat, ....X=1,2,3...
avoir plusieurs paramètres du même nom est rare mais nécessaire pour prendre en charge les paramètres du contrôleur tels que int [], IEnumerable <int>, etc. (ces paramètres peuvent être utilisés pour prendre en charge plusieurs cases à cocher) voir "Plusieurs occurrences de la même variable de chaîne de requête sont consolidées dans une seule entrée" selon le site MS . Une version artisanale de la méthode pourrait être votre seule option
HttpUtility.ParseQueryString fonctionnera tant que vous êtes dans une application Web ou que cela ne vous dérange pas d'inclure une dépendance sur System.Web. Une autre façon de procéder 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);
}
}
?foo=1&bar
. HttpUtility
l'analyserait comme{ key = null, value = "bar" }
Un grand nombre de réponses fournissent des exemples personnalisés en raison de la dépendance de la réponse acceptée à System.Web . À partir du package NuGet Microsoft.AspNet.WebApi.Client , il existe une méthode UriExtensions.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 rouler vous-même, c'est une bonne option.
Je voulais supprimer la dépendance sur System.Web afin que je puisse analyser la chaîne de requête d'un déploiement ClickOnce, tout en ayant les prérequis limités au "Sous-ensemble de cadre 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;
}
J'avais besoin d'une fonction un peu plus polyvalente que ce qui était déjà fourni lors de l'utilisation de requêtes OLSC.
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 de s'attaquer <Extension()>
à cela aussi pour ajouter la capacité à Uri lui-même.
Pour ce faire sans System.Web
, sans l'écrire vous-même et sans packages NuGet supplémentaires:
System.Net.Http.Formatting
using System.Net.Http;
Utilisez ce code:
new Uri(uri).ParseQueryString()
https://msdn.microsoft.com/en-us/library/system.net.http.uriextensions(v=vs.118).aspx
Si vous souhaitez éviter la dépendance à System.Web requise pour utiliser HttpUtility.ParseQueryString , vous pouvez utiliser la Uri
méthode d'extension ParseQueryString
trouvée dans System.Net.Http
.
Assurez-vous d'ajouter une référence (si vous ne l'avez pas déjà fait) à System.Net.Http
dans votre projet.
Notez que vous devez convertir le corps de la réponse en un fichier valide Uri
pour que ParseQueryString
(in System.Net.Http
) fonctionne.
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 ] );
}
}
}
Je viens de réaliser que Web API Client a une ParseQueryString
méthode d'extension qui fonctionne sur a Uri
et retourne a HttpValueCollection
:
var parameters = uri.ParseQueryString();
string foo = parameters["foo"];
HttpUtility.ParseQueryString(Request.Url.Query)
return est 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);
Je viens de fouetter cela à partir du code source de Mono . Il contient le HttpUtility et toutes ses dépendances (comme IHtmlString, Helpers, HttpEncoder, HttpQSCollection).
Ensuite, utilisez HttpUtility.ParseQueryString
.
https://gist.github.com/bjorn-ali-goransson/b04a7c44808bb2de8cca3fc9a3762f9c
Puisque tout le monde semble coller sa solution ... voici la mienne :-) J'en avais besoin depuis une bibliothèque de classes sans System.Web
récupérer les paramètres d'id à partir 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")
Accédez à Request.QueryString.Keys pour un NameValueCollection de tous les paramètres de chaîne de requête.
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
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;
}
Je traduis en version 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;
}
C'est mon code, je pense que c'est très 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;
}