Vorrei analizzare una stringa come p1=6&p2=7&p3=8
in a NameValueCollection
.
Qual è il modo più elegante per farlo quando non hai accesso Page.Request
all'oggetto?
Vorrei analizzare una stringa come p1=6&p2=7&p3=8
in a NameValueCollection
.
Qual è il modo più elegante per farlo quando non hai accesso Page.Request
all'oggetto?
Risposte:
Esiste un'utilità .NET integrata per questo: HttpUtility.ParseQueryString
// C#
NameValueCollection qscoll = HttpUtility.ParseQueryString(querystring);
' VB.NET
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)
Potrebbe essere necessario sostituirlo querystring
con new Uri(fullUrl).Query
.
HttpUtility.ParseQueryString
sarebbe la mia raccomandazione, tranne che nel caso in cui HttpUtility.ParseQueryString("&X=1&X=2&X=3")
il risultato sia ....X=1,2,3...
Avere più parametri con lo stesso nome è raro ma necessario per supportare parametri del controller come int [], IEnumerable <int> ecc (tali parametri potrebbero essere usati per supportare più caselle di controllo) vedere "Le ricorrenze multiple della stessa variabile della stringa di query sono consolidate in una voce" come per sito MS . Una versione artigianale del metodo potrebbe essere la tua unica opzione
HttpUtility.ParseQueryString funzionerà fino a quando ti trovi in un'app Web o non ti dispiace includere una dipendenza da System.Web. Un altro modo per farlo è:
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 analizzerebbe come{ key = null, value = "bar" }
Molte risposte forniscono esempi personalizzati a causa della dipendenza della risposta accettata da System.Web . Dal pacchetto NuGet Microsoft.AspNet.WebApi.Client c'è un UriExtensions.ParseQueryString , metodo che può anche essere usato:
var uri = new Uri("https://stackoverflow.com/a/22167748?p1=6&p2=7&p3=8");
NameValueCollection query = uri.ParseQueryString();
Quindi, se vuoi evitare la dipendenza System.Web e non vuoi farne una tua, questa è una buona opzione.
Volevo rimuovere la dipendenza da System.Web in modo da poter analizzare la stringa di query di una distribuzione ClickOnce, pur avendo i prerequisiti limitati al "Sottoinsieme framework solo client".
Mi è piaciuta la risposta di rp. Ho aggiunto qualche logica aggiuntiva.
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;
}
Avevo bisogno di una funzione un po 'più versatile di quella già fornita quando si lavorava con le query OLSC.
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 puntare anche <Extension()>
su questo per aggiungere la capacità a Uri stesso.
Per fare ciò senza System.Web
, senza scriverlo tu stesso e senza pacchetti NuGet aggiuntivi:
System.Net.Http.Formatting
using System.Net.Http;
Usa questo codice:
new Uri(uri).ParseQueryString()
https://msdn.microsoft.com/en-us/library/system.net.http.uriextensions(v=vs.118).aspx
Se si desidera evitare la dipendenza da System.Web richiesta per utilizzare HttpUtility.ParseQueryString , è possibile utilizzare il Uri
metodo di estensione ParseQueryString
trovato in System.Net.Http
.
Assicurati di aggiungere un riferimento (se non l'hai già fatto) al System.Net.Http
tuo progetto.
Si noti che è necessario convertire il corpo della risposta in un valido in Uri
modo che ParseQueryString
(in System.Net.Http
) funzioni.
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 ] );
}
}
}
Ho appena realizzato che il client API Web ha un ParseQueryString
metodo di estensione che funziona su un Uri
e restituisce un HttpValueCollection
:
var parameters = uri.ParseQueryString();
string foo = parameters["foo"];
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);
Ho appena montato questo insieme dal codice sorgente di Mono . Contiene HttpUtility e tutte le sue dipendenze (come IHtmlString, Helpers, HttpEncoder, HttpQSCollection).
Quindi utilizzare HttpUtility.ParseQueryString
.
https://gist.github.com/bjorn-ali-goransson/b04a7c44808bb2de8cca3fc9a3762f9c
Dal momento che tutti sembrano incollare la sua soluzione .. ecco la mia :-) Ne avevo bisogno all'interno di una libreria di classi senza System.Web
recuperare i parametri ID dai collegamenti ipertestuali memorizzati.
Ho pensato di condividere perché trovo questa soluzione più veloce e più bella.
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")
Hit Request.QueryString.Keys per un NameValueCollection di tutti i parametri della stringa di query.
Per ottenere tutti i valori Querystring prova 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());
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;
}
Traduco in versione C # di josh-brown in 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 sia 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;
}