Chciałbym parsować ciąg taki jak p1=6&p2=7&p3=8
na NameValueCollection
.
Jaki jest najbardziej elegancki sposób, gdy nie masz dostępu do Page.Request
obiektu?
Chciałbym parsować ciąg taki jak p1=6&p2=7&p3=8
na NameValueCollection
.
Jaki jest najbardziej elegancki sposób, gdy nie masz dostępu do Page.Request
obiektu?
Odpowiedzi:
Do tego celu służy wbudowane narzędzie .NET: HttpUtility.ParseQueryString
// C#
NameValueCollection qscoll = HttpUtility.ParseQueryString(querystring);
' VB.NET
Dim qscoll As NameValueCollection = HttpUtility.ParseQueryString(querystring)
Być może trzeba wymienić querystring
z new Uri(fullUrl).Query
.
HttpUtility.ParseQueryString
byłoby moją rekomendacją, z wyjątkiem tego, że w przypadku HttpUtility.ParseQueryString("&X=1&X=2&X=3")
wyniku jest to, że ....X=1,2,3...
posiadanie wielu parametrów o tej samej nazwie jest rzadkie, ale potrzebne do obsługi parametrów kontrolera, takich jak int [], IEnumerable <int> itp. (takich parametrów można użyć do obsługi wielu pól wyboru) patrz „Wiele wystąpień tej samej zmiennej ciągu zapytania jest skonsolidowanych w jednym wpisie” zgodnie z witryną MS . Ręcznie przygotowana wersja metody może być twoją jedyną opcją
HttpUtility.ParseQueryString będzie działać tak długo, jak jesteś w aplikacji internetowej, lub nie przeszkadza ci to zależność od System.Web. Innym sposobem na to jest:
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
parsowałby to jako{ key = null, value = "bar" }
Wiele odpowiedzi zawiera niestandardowe przykłady z powodu zależności zaakceptowanej odpowiedzi od System.Web . Z pakietu Microsoft.AspNet.WebApi.Client NuGet dostępna jest metoda UriExtensions.ParseQueryString , której można również użyć:
var uri = new Uri("https://stackoverflow.com/a/22167748?p1=6&p2=7&p3=8");
NameValueCollection query = uri.ParseQueryString();
Więc jeśli chcesz uniknąć zależności System.Web i nie chcesz tworzyć własnych, jest to dobra opcja.
Chciałem usunąć zależność od System.Web, aby móc przeanalizować ciąg zapytania wdrożenia ClickOnce, mając jednocześnie wymagania wstępne ograniczone do „podzbioru środowiska tylko dla klienta”.
Podobała mi się odpowiedź RP. Dodałem dodatkową logikę.
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;
}
Potrzebowałem funkcji, która jest nieco bardziej uniwersalna niż ta, która była już dostępna podczas pracy z zapytaniami OLSC.
Oto moje rozwiązanie:
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
Być może nie jest to zły pomysł <Extension()>
, aby dodać to samo, aby dodać zdolność do samego Uri.
Aby to zrobić bez System.Web
, bez samodzielnego pisania i bez dodatkowych pakietów NuGet:
System.Net.Http.Formatting
using System.Net.Http;
Użyj tego kodu:
new Uri(uri).ParseQueryString()
https://msdn.microsoft.com/en-us/library/system.net.http.uriextensions(v=vs.118).aspx
Jeśli chcesz uniknąć zależności od System.Web, która jest wymagana do użycia HttpUtility.ParseQueryString , możesz użyć Uri
metody rozszerzenia ParseQueryString
znalezionej w System.Net.Http
.
Pamiętaj, aby dodać odniesienie (jeśli jeszcze tego nie zrobiłeś) do System.Net.Http
swojego projektu.
Pamiętaj, że musisz przekonwertować treść odpowiedzi na poprawną Uri
, aby ParseQueryString
(in System.Net.Http
) działała.
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 ] );
}
}
}
Właśnie zdałem sobie sprawę, że klient Web API ma ParseQueryString
metodę rozszerzenia, która działa na a Uri
i zwraca HttpValueCollection
:
var parameters = uri.ParseQueryString();
string foo = parameters["foo"];
HttpUtility.ParseQueryString(Request.Url.Query)
return is HttpValueCollection
(klasa wewnętrzna). Dziedziczy po 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);
Właśnie wymieszałem to z kodu źródłowego Mono . Zawiera HttpUtility i wszystkie jego zależności (takie jak IHtmlString, Helpers, HttpEncoder, HttpQSCollection).
Następnie użyj HttpUtility.ParseQueryString
.
https://gist.github.com/bjorn-ali-goransson/b04a7c44808bb2de8cca3fc9a3762f9c
Ponieważ wszyscy wydają się wklejać swoje rozwiązanie .. oto moje :-) Potrzebowałem tego z biblioteki klasowej bez System.Web
pobierania parametrów id z przechowywanych hiperłączy.
Myślałem, że podzielę się, ponieważ uważam to rozwiązanie za szybsze i lepiej wyglądające.
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];
}
}
Stosowanie:
Statics.QueryGet(url, "id")
Hit Request.QueryString.Keys dla NameValueCollection wszystkich parametrów ciągu zapytania.
Aby uzyskać wszystkie wartości Querystring, spróbuj:
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;
}
Tłumaczę na josh-brown w wersji C # w 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;
}
To jest mój kod, myślę, że jest bardzo przydatny:
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;
}