Chciałbym parsować ciąg taki jak p1=6&p2=7&p3=8na NameValueCollection.
Jaki jest najbardziej elegancki sposób, gdy nie masz dostępu do Page.Requestobiektu?
Chciałbym parsować ciąg taki jak p1=6&p2=7&p3=8na NameValueCollection.
Jaki jest najbardziej elegancki sposób, gdy nie masz dostępu do Page.Requestobiektu?
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ć querystringz new Uri(fullUrl).Query.
HttpUtility.ParseQueryStringbył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. HttpUtilityparsował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.Formattingusing 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ć Urimetody rozszerzenia ParseQueryStringznalezionej w System.Net.Http.
Pamiętaj, aby dodać odniesienie (jeśli jeszcze tego nie zrobiłeś) do System.Net.Httpswojego 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 ParseQueryStringmetodę rozszerzenia, która działa na a Urii 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.Webpobierania 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;
}