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 NameValueCollectionwerden die Name-Wert-Paare in einem name1=value1&name2=value2Querystring-fähigen Format zurückgegeben. Beachten Sie, dass NameValueCollectionTypen 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.ParseQueryStringMethode tatsächlich ein internes HttpValueCollectionObjekt anstelle eines regulären Objekts zurückgibt NameValueCollection( trotz der angegebenen DokumentationNameValueCollection ). Die HttpValueCollectionkodiert automatisch die Abfragezeichenfolgeflag bei der Verwendung ToString(), so gibt es keine Notwendigkeit , eine Routine zu schreiben , dass Schleifen durch die Sammlung und die verwendete UrlEncodeMethode. 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 ParseQueryStringoben 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 .SetRemovenameValues
NameValueCollection.ToString()kehrt System.Collections.Specialized.NameValueCollectionstring (wörtlich), nicht die „name Wert - Paare in einer Abfragezeichen bereit Format“.
NameValueCollectiondas erwartete Format zurückgegeben wird. Die MSDN-Dokumentation ist auch irreführend, da sie besagt, dass ParseQueryStringa zurückgegeben wird, NameValueCollectionobwohl dies tatsächlich der Fall ist, HttpValueCollectionund 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])));
NameValueCollectionsund nicht das bereitgestellte Szenario beantwortet, das HttpValueCollectionstattdessen 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.ParseQueryStringeine leere Typensammlung zu generieren HttpValueCollection. Diese Klasse ist eine Unterklasse NameValueCollection, die als gekennzeichnet ist, internalsodass Ihr Code keine Instanz davon erstellen kann.
Das Schöne daran HttpValueCollectionist, dass die ToStringMethode 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.QueryStringSammlung 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 NameValueCollectionund es mit der ursprünglichen URL zu kombinieren.
Ich möchte jedoch auf einige Dinge hinweisen:
Sie können nicht HttpUtility.ParseQueryStringauf verwenden Request.RawUrl. Die ParseQueryString()Methode sucht nach einem Wert wie diesem : ?var=value&var2=value2.
Wenn Sie einen NameValueCollectionder QueryStringParameter 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 RequestObjekt zu verwenden, verwenden Sie Uriund die HttpUtility.ParseQueryStringMethode.
Uri uri = new Uri("<THE URL>");
var nv = HttpUtility.ParseQueryString(uri.Query);
string url = String.Format("{0}?{1}", uri.AbsolutePath, nv.ToString());
Request.QueryStringist es eigentlich keine NameValueCollection, sondern eine spezielle Ableitung HttpValueCollection, weshalb es .ToStringfunktioniert. auf einem normalen nvc müssen Sie stattdessen so etwas wie diese Antwort verwenden
Da a NameValueCollectionmehrere 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[]=val2beher 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.QueryStringist 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);