Ich weiß ich kann das
var nv = HttpUtility.ParseQueryString(req.RawUrl);
Aber gibt es eine Möglichkeit, dies wieder in eine URL umzuwandeln?
var newUrl = HttpUtility.Something("/page", nv);
Ich weiß ich kann das
var nv = HttpUtility.ParseQueryString(req.RawUrl);
Aber gibt es eine Möglichkeit, dies wieder in eine URL umzuwandeln?
var newUrl = HttpUtility.Something("/page", nv);
Antworten:
Durch einfaches Aufrufen ToString()
von NameValueCollection
werden die Name-Wert-Paare in einem name1=value1&name2=value2
Querystring-fähigen Format zurückgegeben. Beachten Sie, dass NameValueCollection
Typen dies nicht unterstützen und es irreführend ist, dies vorzuschlagen, aber das Verhalten funktioniert hier aufgrund des internen Typs, der tatsächlich zurückgegeben wird, wie unten erläutert.
Vielen Dank an @mjwills für den Hinweis, dass die HttpUtility.ParseQueryString
Methode tatsächlich ein internes HttpValueCollection
Objekt anstelle eines regulären Objekts zurückgibt NameValueCollection
( trotz der angegebenen DokumentationNameValueCollection
). Die HttpValueCollection
kodiert automatisch die Abfragezeichenfolgeflag bei der Verwendung ToString()
, so gibt es keine Notwendigkeit , eine Routine zu schreiben , dass Schleifen durch die Sammlung und die verwendete UrlEncode
Methode. Das gewünschte Ergebnis wird bereits zurückgegeben.
Mit dem vorliegenden Ergebnis können Sie es dann an die URL anhängen und umleiten:
var nameValues = HttpUtility.ParseQueryString(Request.QueryString.ToString());
string url = Request.Url.AbsolutePath + "?" + nameValues.ToString();
Response.Redirect(url);
Derzeit ist die einzige Möglichkeit, a zu verwenden HttpValueCollection
, die ParseQueryString
oben gezeigte Methode (außer natürlich Reflexion). Es sieht so aus, als würde sich dies nicht ändern, da das Connect-Problem, bei dem diese Klasse veröffentlicht werden soll, mit dem Status "Wird nicht behoben" geschlossen wurde.
Nebenbei können Sie die Methoden ,, und aufrufen Add
, um die Querystring-Elemente vor dem Anhängen zu ändern. Wenn Sie daran interessiert sind, sehen Sie meine Antwort auf eine andere Frage .Set
Remove
nameValues
NameValueCollection.ToString()
kehrt System.Collections.Specialized.NameValueCollection
string (wörtlich), nicht die „name Wert - Paare in einer Abfragezeichen bereit Format“.
NameValueCollection
das erwartete Format zurückgegeben wird. Die MSDN-Dokumentation ist auch irreführend, da sie besagt, dass ParseQueryString
a zurückgegeben wird, NameValueCollection
obwohl dies tatsächlich der Fall ist, HttpValueCollection
und wenn Sie dies aufrufen ToString()
, sollte das erwartete Format zurückgegeben werden, wie in den restlichen Antworten erwähnt.
string q = String.Join("&",
nvc.AllKeys.Select(a => a + "=" + HttpUtility.UrlEncode(nvc[a])));
NameValueCollections
und nicht das bereitgestellte Szenario beantwortet, das HttpValueCollection
stattdessen beinhaltet
string q = String.Join("&", nvc.AllKeys.Select(a => HttpUtility.UrlEncode(a) + "=" + HttpUtility.UrlEncode(nvc[a])));
Erstellen Sie eine Erweiterungsmethode, die einige Schleifen verwendet. Ich bevorzuge diese Lösung, weil sie lesbar ist (kein Linq), keine System.Web.HttpUtility erfordert und doppelte Schlüssel verarbeitet.
public static string ToQueryString(this NameValueCollection nvc)
{
if (nvc == null) return string.Empty;
StringBuilder sb = new StringBuilder();
foreach (string key in nvc.Keys)
{
if (string.IsNullOrWhiteSpace(key)) continue;
string[] values = nvc.GetValues(key);
if (values == null) continue;
foreach (string value in values)
{
sb.Append(sb.Length == 0 ? "?" : "&");
sb.AppendFormat("{0}={1}", Uri.EscapeDataString(key), Uri.EscapeDataString(value));
}
}
return sb.ToString();
}
var queryParams = new NameValueCollection()
{
{ "order_id", "0000" },
{ "item_id", "1111" },
{ "item_id", "2222" },
{ null, "skip entry with null key" },
{ "needs escaping", "special chars ? = &" },
{ "skip entry with null value", null }
};
Console.WriteLine(queryParams.ToQueryString());
?order_id=0000&item_id=1111&item_id=2222&needs%20escaping=special%20chars%20%3F%20%3D%20%26
Dies sollte ohne zu viel Code funktionieren:
NameValueCollection nameValues = HttpUtility.ParseQueryString(String.Empty);
nameValues.Add(Request.QueryString);
// modify nameValues if desired
var newUrl = "/page?" + nameValues;
Die Idee ist, HttpUtility.ParseQueryString
eine leere Typensammlung zu generieren HttpValueCollection
. Diese Klasse ist eine Unterklasse NameValueCollection
, die als gekennzeichnet ist, internal
sodass Ihr Code keine Instanz davon erstellen kann.
Das Schöne daran HttpValueCollection
ist, dass die ToString
Methode die Codierung für Sie übernimmt. Durch die Nutzung der NameValueCollection.Add(NameValueCollection)
Methode können Sie die vorhandenen Parameter für Abfragezeichenfolgen zu Ihrem neu erstellten Objekt hinzufügen, ohne die Request.QueryString
Sammlung zuerst in eine URL-codierte Zeichenfolge konvertieren und dann wieder in eine Sammlung analysieren zu müssen.
Diese Technik kann auch als Erweiterungsmethode verwendet werden:
public static string ToQueryString(this NameValueCollection nameValueCollection)
{
NameValueCollection httpValueCollection = HttpUtility.ParseQueryString(String.Empty);
httpValueCollection.Add(nameValueCollection);
return httpValueCollection.ToString();
}
Eigentlich sollten Sie auch den Schlüssel codieren, nicht nur den Wert.
string q = String.Join("&",
nvc.AllKeys.Select(a => $"{HttpUtility.UrlEncode(a)}={HttpUtility.UrlEncode(nvc[a])}"));
Die kurze Antwort ist, .ToString()
auf dem zu verwenden NameValueCollection
und es mit der ursprünglichen URL zu kombinieren.
Ich möchte jedoch auf einige Dinge hinweisen:
Sie können nicht HttpUtility.ParseQueryString
auf verwenden Request.RawUrl
. Die ParseQueryString()
Methode sucht nach einem Wert wie diesem : ?var=value&var2=value2
.
Wenn Sie einen NameValueCollection
der QueryString
Parameter erhalten möchten, verwenden Sie einfach Request.QueryString()
.
var nv = Request.QueryString;
Um die URL neu zu erstellen, verwenden Sie einfach nv.ToString ().
string url = String.Format("{0}?{1}", Request.Path, nv.ToString());
Wenn Sie versuchen, eine URL-Zeichenfolge zu analysieren, anstatt das Request
Objekt zu verwenden, verwenden Sie Uri
und die HttpUtility.ParseQueryString
Methode.
Uri uri = new Uri("<THE URL>");
var nv = HttpUtility.ParseQueryString(uri.Query);
string url = String.Format("{0}?{1}", uri.AbsolutePath, nv.ToString());
Request.QueryString
ist es eigentlich keine NameValueCollection
, sondern eine spezielle Ableitung HttpValueCollection
, weshalb es .ToString
funktioniert. auf einem normalen nvc müssen Sie stattdessen so etwas wie diese Antwort verwenden
Da a NameValueCollection
mehrere Werte für denselben Schlüssel haben kann, können Sie Folgendes berücksichtigen, wenn Sie sich mit dem Format des Abfragerings befassen (da dieser als durch Kommas getrennte Werte und nicht als "Array-Notation" zurückgegeben wird).
var nvc = new NameValueCollection();
nvc.Add("key1", "val1");
nvc.Add("key2", "val2");
nvc.Add("empty", null);
nvc.Add("key2", "val2b");
Verwandeln Sie sich in: key1=val1&key2[]=val2&empty&key2[]=val2b
eher als key1=val1&key2=val2,val2b&empty
.
string qs = string.Join("&",
// "loop" the keys
nvc.AllKeys.SelectMany(k => {
// "loop" the values
var values = nvc.GetValues(k);
if(values == null) return new[]{ k };
return nvc.GetValues(k).Select( (v,i) =>
// 'gracefully' handle formatting
// when there's 1 or more values
string.Format(
values.Length > 1
// pick your array format: k[i]=v or k[]=v, etc
? "{0}[]={1}"
: "{0}={1}"
, k, HttpUtility.UrlEncode(v), i)
);
})
);
oder wenn du Linq nicht so sehr magst ...
string qs = nvc.ToQueryString(); // using...
public static class UrlExtensions {
public static string ToQueryString(this NameValueCollection nvc) {
return string.Join("&", nvc.GetUrlList());
}
public static IEnumerable<string> GetUrlList(this NameValueCollection nvc) {
foreach(var k in nvc.AllKeys) {
var values = nvc.GetValues(k);
if(values == null) { yield return k; continue; }
for(int i = 0; i < values.Length; i++) {
yield return
// 'gracefully' handle formatting
// when there's 1 or more values
string.Format(
values.Length > 1
// pick your array format: k[i]=v or k[]=v, etc
? "{0}[]={1}"
: "{0}={1}"
, k, HttpUtility.UrlEncode(values[i]), i);
}
}
}
}
Wie bereits in den Kommentaren erwähnt, befassen sich die meisten anderen Antworten mit Ausnahme dieser Antwort eher mit dem Szenario ( Request.QueryString
ist ein HttpValueCollection
"nicht" a NameValueCollection
) als mit der wörtlichen Frage.
Update: Nullwertproblem aus Kommentar behoben.
In AspNet Core 2.0 können Sie die QueryHelpers AddQueryString-Methode verwenden.
Ich verwende UriBuilder immer, um eine URL mit einem Querystring zurück in eine gültige und ordnungsgemäß codierte URL zu konvertieren.
var url = "http://my-link.com?foo=bar";
var uriBuilder = new UriBuilder(url);
var query = HttpUtility.ParseQueryString(uriBuilder.Query);
query.Add("yep", "foo&bar");
uriBuilder.Query = query.ToString();
var result = uriBuilder.ToString();
// http://my-link.com:80/?foo=bar&yep=foo%26bar
Wie von @Atchitutchuk vorgeschlagen, können Sie QueryHelpers.AddQueryString in ASP.NET Core verwenden:
public string FormatParameters(NameValueCollection parameters)
{
var queryString = "";
foreach (var key in parameters.AllKeys)
{
foreach (var value in parameters.GetValues(key))
{
queryString = QueryHelpers.AddQueryString(queryString, key, value);
}
};
return queryString.TrimStart('?');
}
Sie können verwenden.
var ur = new Uri("/page",UriKind.Relative);
Wenn dieses nv vom Typ string ist, können Sie es an den ersten Parameter uri anhängen. Mögen
var ur2 = new Uri("/page?"+nv.ToString(),UriKind.Relative);