Wie erstelle ich eine Abfragezeichenfolge für eine URL in C #?


473

Eine häufige Aufgabe beim Aufrufen von Webressourcen aus einem Code besteht darin, eine Abfragezeichenfolge zu erstellen, die alle erforderlichen Parameter enthält. Während es auf keinen Fall eine Raketenwissenschaft gibt, gibt es einige raffinierte Details, um die Sie sich kümmern müssen, wie das Anhängen eines, &wenn nicht des ersten Parameters, das Codieren der Parameter usw.

Der Code dafür ist sehr einfach, aber etwas langweilig:

StringBuilder SB = new StringBuilder();
if (NeedsToAddParameter A) 
{ 
  SB.Append("A="); SB.Append(HttpUtility.UrlEncode("TheValueOfA")); 
}

if (NeedsToAddParameter B) 
{
  if (SB.Length>0) SB.Append("&"); 
  SB.Append("B="); SB.Append(HttpUtility.UrlEncode("TheValueOfB")); }
}

Dies ist eine so häufige Aufgabe, dass man erwarten würde, dass eine Utility-Klasse existiert, die sie eleganter und lesbarer macht. Beim Scannen von MSDN konnte ich keine finden - was mich zu der folgenden Frage bringt:

Was ist die eleganteste und sauberste Art, wie Sie das oben genannte tun?


26
Es ist ein bisschen traurig, dass es selbst zum gegenwärtigen Zeitpunkt keinen einfachen Weg zu geben scheint, mit Querystringen umzugehen. Und mit unkompliziert meine ich eine OOB, nicht interne, standardkonforme Framework-Klasse. Oder verpasse ich vielleicht etwas?
Grimasse der Verzweiflung

5
Du vermisst nichts. Querystring Building ist eine große Lücke in dem Framework, das ich mit Flurl zu füllen versucht habe .
Todd Menier


Du hast mich gerade zum Nachdenken gebracht, ich sollte einen bauen. Neuer UrlBuilder (vorhanden) .AddQuery ("Schlüssel", "Wert"). ToString ()
Demetris Leptos

Antworten:


293

Wenn Sie unter die Haube schauen, ist die QueryString-Eigenschaft eine NameValueCollection. Wenn ich ähnliche Dinge getan habe, war ich normalerweise an Serialisierung UND Deserialisierung interessiert. Mein Vorschlag ist daher, eine NameValueCollection aufzubauen und dann an folgende Adresse zu übergeben:

using System.Linq;
using System.Web;
using System.Collections.Specialized;

private string ToQueryString(NameValueCollection nvc)
{
    var array = (
        from key in nvc.AllKeys
        from value in nvc.GetValues(key)
            select string.Format(
                "{0}={1}",
                HttpUtility.UrlEncode(key),
                HttpUtility.UrlEncode(value))
        ).ToArray();
    return "?" + string.Join("&", array);
}

Ich kann mir vorstellen, dass es auch in LINQ eine super elegante Möglichkeit gibt, dies zu tun ...


22
Die HTTP-Spezifikation (RFC 2616) sagt nichts darüber aus, was Abfragezeichenfolgen enthalten können. Auch RFC 3986, das das generische URI-Format definiert, nicht. Das häufig verwendete Schlüssel / Wert-Paar-Format wird aufgerufen application/x-www-form-urlencodedund tatsächlich durch HTML definiert, um Formulardaten als Teil einer GETAnforderung zu senden. HTML 5 verbietet nicht mehrere Werte pro Schlüssel in diesem Format. Tatsächlich muss der Browser mehrere Werte pro Schlüssel erstellen, falls die Seite (fälschlicherweise) mehrere Felder mit demselben nameAttribut enthält. Siehe goo.gl/uk1Ag
Daniel Cassidy

14
@annakata: Ich weiß, dass mein Kommentar über ein Jahr alt ist (und die Antwort über zwei Jahre alt!), aber NameValueCollection unterstützt mithilfe der GetValues ​​(Schlüssel) -Methode sehr viele Werte pro Schlüssel.
Mauricio Scheffer

4
@MauricioScheffer: Aber NameValueCollection verwandelt sich nicht "richtig" in einen Querystring. Wenn Sie beispielsweise den QueryString-Parameter in WebClient festlegen, bei dem derselbe Schlüssel mehrmals vorhanden ist, wird er zu "Pfad? Schlüssel = Wert1, Wert2" anstelle von "Pfad? Schlüssel = Wert1 & Schlüssel = Wert2", was ein allgemeiner Standard ist ?) Muster.
David Pope

8
In Bezug auf mehrere Werte pro Schlüssel glaube ich, dass in HTML, wenn Sie ein Mehrfachauswahl-Listenfeld mit mehreren ausgewählten und übermittelten Elementen haben, diese in dem von David genannten Mehrfachwertformat gesendet werden.
Sam

10
Möglicherweise möchten Sie Uri.EscapeDataString anstelle von HttpUtility.UrlEncode verwenden, das portabler ist. Siehe stackoverflow.com/questions/2573290/…
PEK

687

Sie können eine neue beschreibbare Instanz von erstellen, HttpValueCollectionindem Sie sie aufrufen System.Web.HttpUtility.ParseQueryString(string.Empty)und dann wie eine beliebige verwenden NameValueCollection. Nachdem Sie die gewünschten Werte hinzugefügt haben, können Sie ToStringdie Sammlung wie folgt aufrufen , um eine Abfragezeichenfolge abzurufen:

NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(string.Empty);

queryString.Add("key1", "value1");
queryString.Add("key2", "value2");

return queryString.ToString(); // Returns "key1=value1&key2=value2", all URL-encoded

Das HttpValueCollectionist intern und daher können Sie keine Instanz direkt erstellen. Sobald Sie jedoch eine Instanz erhalten haben, können Sie sie wie jede andere verwenden NameValueCollection. Da das eigentliche Objekt, mit dem Sie arbeiten, ein ist HttpValueCollection, ruft das Aufrufen der ToString-Methode die überschriebene Methode auf HttpValueCollection, mit der die Auflistung als URL-codierte Abfragezeichenfolge formatiert wird .

Nachdem ich SO und das Web nach einer Antwort auf ein ähnliches Problem durchsucht habe, ist dies die einfachste Lösung, die ich finden konnte.

.NET Core

Wenn Sie in .NET Core arbeiten, können Sie die Microsoft.AspNetCore.WebUtilities.QueryHelpersKlasse verwenden, was dies erheblich vereinfacht.

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.webutilities.queryhelpers

Beispielcode:

const string url = "https://customer-information.azure-api.net/customers/search/taxnbr";
var param = new Dictionary<string, string>() { { "CIKey", "123456789" } };

var newUrl = new Uri(QueryHelpers.AddQueryString(url, param));

6
Sie könnten wahrscheinlich eine Erweiterungsmethode namens ToURLQueryString für die IDictionary-Schnittstelle erstellen:public static string ToURLQueryString(this IDictionary dict) { ... }
Roy Tinker

65
Diese Methode ist für Multibyte-Zeichen nicht standardkonform . Sie werden als% uXXXX anstelle von% XX% XX codiert. Die resultierenden Abfragezeichenfolgen werden von Webservern möglicherweise falsch interpretiert. Dies ist sogar in der internen Framework-Klasse HttpValueCollection dokumentiert, die von HttpUtility.ParseQueryString () zurückgegeben wird. Kommentar besagt, dass sie dieses Verhalten aus Gründen der Abwärtskompatibilität beibehalten.
alex

25
Beachten Sie, dass es einen wichtigen Unterschied zwischen HttpUtilityPraseQueryString ("") und neuer NameValueCollection () gibt - nur das HttpUtility-Ergebnis überschreibt ToString (), um einen ordnungsgemäßen Querystring zu erzeugen
Frank Schwieterman

7
Was ist mit Fällen, in denen Sie mehrere Instanzen eines Namens in der Abfragezeichenfolge möchten? Zum Beispiel "Typ = 10 & Typ = 21".
Finster

7
@Finster Mit der AddMethode können Sie der Abfragezeichenfolge mehrere Instanzen eines Namens hinzufügen . Das heißt, die queryString.Add("type", "1"); queryString.Add("type", "2"); Verwendung der AddMethode ist wahrscheinlich eine bessere Möglichkeit, dies die ganze Zeit tatsächlich zu tun.
jeremysawesome

94

Mit der Inspiration von Roy Tinkers Kommentar habe ich eine einfache Erweiterungsmethode für die Uri-Klasse verwendet, die meinen Code präzise und sauber hält:

using System.Web;

public static class HttpExtensions
{
    public static Uri AddQuery(this Uri uri, string name, string value)
    {
        var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);

        httpValueCollection.Remove(name);
        httpValueCollection.Add(name, value);

        var ub = new UriBuilder(uri);
        ub.Query = httpValueCollection.ToString();

        return ub.Uri;
    }
}

Verwendungszweck:

Uri url = new Uri("http://localhost/rest/something/browse").
          AddQuery("page", "0").
          AddQuery("pageSize", "200");

Bearbeiten - Standardkonforme Variante

Wie mehrere Personen betonten, werden httpValueCollection.ToString()Unicode-Zeichen nicht standardkonform codiert . Dies ist eine Variante derselben Erweiterungsmethode, die solche Zeichen durch Aufrufen der HttpUtility.UrlEncodeMethode anstelle der veralteten HttpUtility.UrlEncodeUnicodeMethode behandelt.

using System.Web;

public static Uri AddQuery(this Uri uri, string name, string value)
{
    var httpValueCollection = HttpUtility.ParseQueryString(uri.Query);

    httpValueCollection.Remove(name);
    httpValueCollection.Add(name, value);

    var ub = new UriBuilder(uri);

    // this code block is taken from httpValueCollection.ToString() method
    // and modified so it encodes strings with HttpUtility.UrlEncode
    if (httpValueCollection.Count == 0)
        ub.Query = String.Empty;
    else
    {
        var sb = new StringBuilder();

        for (int i = 0; i < httpValueCollection.Count; i++)
        {
            string text = httpValueCollection.GetKey(i);
            {
                text = HttpUtility.UrlEncode(text);

                string val = (text != null) ? (text + "=") : string.Empty;
                string[] vals = httpValueCollection.GetValues(i);

                if (sb.Length > 0)
                    sb.Append('&');

                if (vals == null || vals.Length == 0)
                    sb.Append(val);
                else
                {
                    if (vals.Length == 1)
                    {
                        sb.Append(val);
                        sb.Append(HttpUtility.UrlEncode(vals[0]));
                    }
                    else
                    {
                        for (int j = 0; j < vals.Length; j++)
                        {
                            if (j > 0)
                                sb.Append('&');

                            sb.Append(val);
                            sb.Append(HttpUtility.UrlEncode(vals[j]));
                        }
                    }
                }
            }
        }

        ub.Query = sb.ToString();
    }

    return ub.Uri;
}

3
Perfekt. Zu meiner hauseigenen Bibliothek hinzugefügt. :)
Andy

1
Sie sollten den Wert auch per URL codieren. queryString.Add (Name, Uri.EscapeDataString (Wert));
Ufuk Hacıoğulları

2
Vielen Dank für die Verbesserung dieser Antwort. Das Problem mit Multibyte-Zeichen wurde behoben.
Ufuk Hacıoğulları

9
Nebenbei bemerkt, dies funktioniert nicht mit relativen URLs, da Sie den UriBuilder nicht von einem relativen Uri instanziieren können.
Yuriy Faktorovich

1
Ich habe einen Entfernungsschlüssel hinzugefügt, damit kein Duplikat hinzugefügt werden kann. dotnetfiddle.net/hTlyAd
Paul Totzke

29

Ich habe vor einiger Zeit eine ähnliche Frage beantwortet . Grundsätzlich ist es am besten, die Klasse zu verwenden HttpValueCollection, die Request.QueryStringeigentlich die Eigenschaft von ASP.NET ist. Leider ist sie im .NET Framework intern. Sie können Reflector verwenden, um es zu greifen (und es in Ihre Utils-Klasse zu legen). Auf diese Weise können Sie die Abfragezeichenfolge wie eine NameValueCollection bearbeiten, wobei jedoch alle Probleme mit der URL-Codierung / -Decodierung behoben sind.

HttpValueCollectionwird erweitert NameValueCollectionund verfügt über einen Konstruktor, der eine codierte Abfragezeichenfolge (einschließlich kaufmännisches Und und Fragezeichen) verwendet und eine ToString()Methode überschreibt , mit der die Abfragezeichenfolge später aus der zugrunde liegenden Auflistung neu erstellt werden kann.

Beispiel:

  var coll = new HttpValueCollection();

  coll["userId"] = "50";
  coll["paramA"] = "A";
  coll["paramB"] = "B";      

  string query = coll.ToString(true); // true means use urlencode

  Console.WriteLine(query); // prints: userId=50&paramA=A&paramB=B

Vielen Dank ... Ich habe festgestellt, dass die zurückgegebene NameValueCollection einen ToString () hat, der sich anders verhält, aber nicht herausfinden kann, warum.
Calebt

httpValueCollection.ToString()ruft tatsächlich an, httpValueCollection.ToString(true)so dass das Hinzufügen der trueExplizität nicht erforderlich ist.
Dav_i

5
HttpValueCollection ist eine interne Klasse, daher können Sie sie nicht instanziieren.
Ozba

29

Hier ist eine fließende / lambda-artige Methode als Erweiterungsmethode (Kombination von Konzepten in früheren Beiträgen), die mehrere Werte für denselben Schlüssel unterstützt. Meine persönliche Präferenz sind Erweiterungen gegenüber Wrappern, damit andere Teammitglieder solche Dinge entdecken können. Beachten Sie, dass es Kontroversen um Codierungsmethoden gibt, viele Beiträge dazu auf Stack Overflow (ein solcher Beitrag ) und MSDN-Blogger (wie dieser ).

public static string ToQueryString(this NameValueCollection source)
{
    return String.Join("&", source.AllKeys
        .SelectMany(key => source.GetValues(key)
            .Select(value => String.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value))))
        .ToArray());
}

Bearbeiten: mit Null-Unterstützung, obwohl Sie es wahrscheinlich an Ihre spezielle Situation anpassen müssen

public static string ToQueryString(this NameValueCollection source, bool removeEmptyEntries)
{
    return source != null ? String.Join("&", source.AllKeys
        .Where(key => !removeEmptyEntries || source.GetValues(key)
            .Where(value => !String.IsNullOrEmpty(value))
            .Any())
        .SelectMany(key => source.GetValues(key)
            .Where(value => !removeEmptyEntries || !String.IsNullOrEmpty(value))
            .Select(value => String.Format("{0}={1}", HttpUtility.UrlEncode(key), value != null ? HttpUtility.UrlEncode(value) : string.Empty)))
        .ToArray())
        : string.Empty;
}

1
Dies schlägt fehl, wenn einer der Werte null ist
Josh Noe

Dies ist falsch, es generiert viele Abfragezeichenfolgen für jedes Schlüsselwertpaar
Gayan

@GayanRanasinghe: Was bedeutet das überhaupt?
Matti Virkkunen

22

Flurl [Offenlegung: Ich bin der Autor] unterstützt das Erstellen von Abfragezeichenfolgen über anonyme Objekte (unter anderem):

var url = "http://www.some-api.com".SetQueryParams(new
{
    api_key = ConfigurationManager.AppSettings["SomeApiKey"],
    max_results = 20,
    q = "Don't worry, I'll get encoded!"
});

Mit der optionalen Begleitbibliothek Flurl.Http können Sie HTTP-Aufrufe direkt in derselben fließenden Aufrufkette ausführen und sie zu einem vollständigen REST-Client erweitern:

T result = await "https://api.mysite.com"
    .AppendPathSegment("person")
    .SetQueryParams(new { ap_key = "my-key" })
    .WithOAuthBearerToken("MyToken")
    .PostJsonAsync(new { first_name = firstName, last_name = lastName })
    .ReceiveJson<T>();

Das vollständige Paket ist auf NuGet verfügbar:

PM> Install-Package Flurl.Http

oder nur der eigenständige URL-Builder:

PM> Install-Package Flurl


20

Hier ist mein später Eintrag. Ich mochte keinen der anderen aus verschiedenen Gründen, also schrieb ich meinen eigenen.

Diese Version bietet:

  • Nur Verwendung von StringBuilder. Keine ToArray () -Aufrufe oder andere Erweiterungsmethoden. Es sieht nicht so hübsch aus wie einige der anderen Antworten, aber ich halte dies für eine Kernfunktion, daher ist Effizienz wichtiger als "fließender" "Einzeiler" -Code, der Ineffizienzen verbirgt.

  • Behandelt mehrere Werte pro Schlüssel. (Ich brauchte es nicht selbst, sondern nur um Mauricio zum Schweigen zu bringen;)

    public string ToQueryString(NameValueCollection nvc)
    {
        StringBuilder sb = new StringBuilder("?");
    
        bool first = true;
    
        foreach (string key in nvc.AllKeys)
        {
            foreach (string value in nvc.GetValues(key))
            {
                if (!first)
                {
                    sb.Append("&");
                }
    
                sb.AppendFormat("{0}={1}", Uri.EscapeDataString(key), Uri.EscapeDataString(value));
    
                first = false;
            }
        }
    
        return sb.ToString();
    }

Beispiel Verwendung

        var queryParams = new NameValueCollection()
        {
            { "x", "1" },
            { "y", "2" },
            { "foo", "bar" },
            { "foo", "baz" },
            { "special chars", "? = &" },
        };

        string url = "http://example.com/stuff" + ToQueryString(queryParams);

        Console.WriteLine(url);

Ausgabe

http://example.com/stuff?x=1&y=2&foo=bar&foo=baz&special%20chars=%3F%20%3D%20%26

Ich mag, dass dies nicht HttpUtility verwendet, das sich unter System.Web befindet und nicht überall verfügbar ist.
Kugel

+1 für die Nichtverwendung von linq und die Verwendung von HttpUtility. Ich würde ein leeres jdn erstellen und die Variable "bool first" fallen lassen und dann in der Schleife einfach sb.Append (sb.Length == 0? "?": "&") Vor dem sb.AppendFormat () haben. Wenn nvc leer ist, gibt die Methode eine leere Zeichenfolge anstelle eines einsamen "?" Zurück.
Mathew Leger

Diese Antwort behandelt einzelne Parameter mit mehreren Werten. zB? id = 1 & id = 3 & id = 2 & id = 9
Mathemats

12

Wie wäre es mit Erweiterungsmethoden, mit denen Sie die Parameter in einem fließenden Stil wie diesem hinzufügen können?

string a = "http://www.somedomain.com/somepage.html"
    .AddQueryParam("A", "TheValueOfA")
    .AddQueryParam("B", "TheValueOfB")
    .AddQueryParam("Z", "TheValueOfZ");

string b = new StringBuilder("http://www.somedomain.com/anotherpage.html")
    .AddQueryParam("A", "TheValueOfA")
    .AddQueryParam("B", "TheValueOfB")
    .AddQueryParam("Z", "TheValueOfZ")
    .ToString(); 

Hier ist die Überladung, die Folgendes verwendet string:

public static string AddQueryParam(
    this string source, string key, string value)
{
    string delim;
    if ((source == null) || !source.Contains("?"))
    {
        delim = "?";
    }
    else if (source.EndsWith("?") || source.EndsWith("&"))
    {
        delim = string.Empty;
    }
    else
    {
        delim = "&";
    }

    return source + delim + HttpUtility.UrlEncode(key)
        + "=" + HttpUtility.UrlEncode(value);
}

Und hier ist die Überlastung, die Folgendes verwendet StringBuilder:

public static StringBuilder AddQueryParam(
    this StringBuilder source, string key, string value)
{
    bool hasQuery = false;
    for (int i = 0; i < source.Length; i++)
    {
        if (source[i] == '?')
        {
            hasQuery = true;
            break;
        }
    }

    string delim;
    if (!hasQuery)
    {
        delim = "?";
    }
    else if ((source[source.Length - 1] == '?')
        || (source[source.Length - 1] == '&'))
    {
        delim = string.Empty;
    }
    else
    {
        delim = "&";
    }

    return source.Append(delim).Append(HttpUtility.UrlEncode(key))
        .Append("=").Append(HttpUtility.UrlEncode(value));
}

: +1: für die einfache String-basierte Erweiterungsmethode. Einige der anderen Antworten können mehr Grenzfälle abdecken, aber das ist für meine Situation ausreichend, und es nicht erforderlich ist mir eine zu konstruieren NameValueCollection, HttpValueCollectionoder ein Uriersten. Vielen Dank!
Stanley G.

11

Ich musste das gleiche Problem für eine tragbare Klassenbibliothek (PCL) lösen, an der ich arbeite. In diesem Fall habe ich keinen Zugriff auf System.Web, daher kann ich ParseQueryString nicht verwenden.

Stattdessen habe ich System.Net.Http.FormUrlEncodedContentso verwendet:

var url = new UriBuilder("http://example.com");

url.Query = new FormUrlEncodedContent(new Dictionary<string,string>()
{
    {"param1", "val1"},
    {"param2", "val2"},
    {"param3", "val3"},
}).ReadAsStringAsync().Result;

Dies ist die Technik, die ich verwende und auf die ich in einer anderen Frage verwiesen habe: http://stackoverflow.com/a/26744471/2108310 Der einzige Unterschied besteht darin, dass ich ein Array von KeyValue-Paaren verwende ... außer dass ich den Verweis auf System benötige. Net (das ist PCL verfügbar, wie Sie angegeben haben) Dies ist meiner Meinung nach der einfachste Weg, dies zu tun, ohne ein Paket eines Drittanbieters einzuschließen oder zu versuchen, ein Homebrew-Spaghetti-Durcheinander zusammen zu humpeln.
Rostow

9
    public static string ToQueryString(this Dictionary<string, string> source)
    {
        return String.Join("&", source.Select(kvp => String.Format("{0}={1}", HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value))).ToArray());
    }

    public static string ToQueryString(this NameValueCollection source)
    {
        return String.Join("&", source.Cast<string>().Select(key => String.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(source[key]))).ToArray());
    }

1
Nett! Aber du brauchst das .ToArray()s nicht.
Mpen

7

Fügen Sie diese Klasse Ihrem Projekt hinzu

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

public class QueryStringBuilder
{
    private readonly List<KeyValuePair<string, object>> _list;

    public QueryStringBuilder()
    {
        _list = new List<KeyValuePair<string, object>>();
    }

    public void Add(string name, object value)
    {
        _list.Add(new KeyValuePair<string, object>(name, value));
    }

    public override string ToString()
    {
        return String.Join("&", _list.Select(kvp => String.Concat(Uri.EscapeDataString(kvp.Key), "=", Uri.EscapeDataString(kvp.Value.ToString()))));
    }
}

Und benutze es so:

var actual = new QueryStringBuilder {
    {"foo", 123},
    {"bar", "val31"},
    {"bar", "val32"}
};

actual.Add("a+b", "c+d");

actual.ToString(); // "foo=123&bar=val31&bar=val32&a%2bb=c%2bd"

Dies sollte die akzeptierte Antwort sein. funktioniert perfekt für Arrays wie "foo [] = 1, foo [] = 2" sowie für die Beibehaltung der Reihenfolge der Parameter, was übrigens sehr wichtig ist.
Soroush Falahati

6

Mein Angebot:

public static Uri AddQuery(this Uri uri, string name, string value)
{
    // this actually returns HttpValueCollection : NameValueCollection
    // which uses unicode compliant encoding on ToString()
    var query = HttpUtility.ParseQueryString(uri.Query);

    query.Add(name, value);

    var uriBuilder = new UriBuilder(uri)
    {
        Query = query.ToString()
    };

    return uriBuilder.Uri;
}

Verwendungszweck:

var uri = new Uri("http://stackoverflow.com").AddQuery("such", "method")
                                             .AddQuery("wow", "soFluent");

// http://stackoverflow.com?such=method&wow=soFluent

Ich bevorzuge Ihren Ansatz Einfach und elegant, jedoch erfordert HttpUtility System.Web
Ody

5

Ungetestet, aber ich denke, etwas in dieser Richtung würde ganz gut funktionieren

public class QueryString
{
    private Dictionary<string,string> _Params = new Dictionary<string,string>();

    public overide ToString()
    {
        List<string> returnParams = new List<string>();

        foreach (KeyValuePair param in _Params)
        {
            returnParams.Add(String.Format("{0}={1}", param.Key, param.Value));
        }

        // return String.Format("?{0}", String.Join("&", returnParams.ToArray())); 

        // credit annakata
        return "?" + String.Join("&", returnParams.ToArray());
    }

    public void Add(string key, string value)
    {
        _Params.Add(key, HttpUtility.UrlEncode(value));
    }
}

QueryString query = new QueryString();

query.Add("param1", "value1");
query.Add("param2", "value2");

return query.ToString();

schön gekapselt, aber das Format auf "? {0}" ist irgendwie unnötig teuer :)
Annakata

Der Klassenname wurde in QueryString geändert. Die Abfrage ist etwas mehrdeutig
Nick Allen

4

Eine auf einer schnellen Erweiterungsmethode basierende Version:

class Program
{
    static void Main(string[] args)
    {
        var parameters = new List<KeyValuePair<string, string>>
                             {
                                 new KeyValuePair<string, string>("A", "AValue"),
                                 new KeyValuePair<string, string>("B", "BValue")
                             };

        string output = "?" + string.Join("&", parameters.ConvertAll(param => param.ToQueryString()).ToArray());
    }
}

public static class KeyValueExtensions
{
    public static string ToQueryString(this KeyValuePair<string, string> obj)
    {
        return obj.Key + "=" + HttpUtility.UrlEncode(obj.Value);
    }
}

Sie können eine where-Klausel verwenden, um auszuwählen, welche Parameter der Zeichenfolge hinzugefügt werden.


3

Angenommen, Sie möchten Abhängigkeiten zu anderen Assemblys reduzieren und die Dinge einfach halten, können Sie Folgendes tun:

var sb = new System.Text.StringBuilder();

sb.Append("a=" + HttpUtility.UrlEncode("TheValueOfA") + "&");
sb.Append("b=" + HttpUtility.UrlEncode("TheValueOfB") + "&");
sb.Append("c=" + HttpUtility.UrlEncode("TheValueOfC") + "&");
sb.Append("d=" + HttpUtility.UrlEncode("TheValueOfD") + "&");

sb.Remove(sb.Length-1, 1); // Remove the final '&'

string result = sb.ToString();

Dies funktioniert auch gut mit Schleifen. Die endgültige Entfernung des kaufmännischen Und muss außerhalb der Schleife erfolgen.

Beachten Sie, dass der Verkettungsoperator verwendet wird, um die Lesbarkeit zu verbessern. Die Kosten für die Verwendung im Vergleich zu den Kosten für die Verwendung eines StringBuilder sind minimal (ich denke, Jeff Atwood hat etwas zu diesem Thema gepostet).


3

Kombinierte die Top-Antworten, um eine anonyme Objektversion zu erstellen :

var queryString = HttpUtility2.BuildQueryString(new
{
    key2 = "value2",
    key1 = "value1",
});

Das erzeugt dies:

Schlüssel2 = Wert2 & Schlüssel1 = Wert1

Hier ist der Code:

public static class HttpUtility2
{
    public static string BuildQueryString<T>(T obj)
    {
        var queryString = HttpUtility.ParseQueryString(string.Empty);

        foreach (var property in TypeDescriptor.GetProperties(typeof(T)).Cast<PropertyDescriptor>())
        {
            var value = (property.GetValue(obj) ?? "").ToString();
            queryString.Add(property.Name, value);
        }

        return queryString.ToString();
    }
}

2

Wie akzeptierte Lösung, jedoch auf "Punkt" -LINQ-Syntax übertragen ...

private string ToQueryString(NameValueCollection nvc)
{
    if (nvc == null) return String.Empty;
    var queryParams = 
          string.Join("&", nvc.AllKeys.Select(key => 
              string.Join("&", nvc.GetValues(key).Select(v => string.Format("{0}={1}", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(v))))));
    return "?" + queryParams;
}

2

Ich habe eine Erweiterungsmethode für Uri , die:

  • Akzeptiert anonyme Objekte: uri.WithQuery(new { name = "value" })
  • Akzeptiert Sammlungen von string/stringPaaren (z . B. Dictionary`2 ).
  • Akzeptiert Sammlungen von string/objectPaaren (z . B. RouteValueDictionary ).
  • Akzeptiert NameValueCollection s.
  • Sortiert die Abfragewerte nach Schlüssel, sodass dieselben Werte gleiche URIs erzeugen.
  • Unterstützt mehrere Werte pro Schlüssel, wobei die ursprüngliche Reihenfolge beibehalten wird.

Die dokumentierte Version finden Sie hier .

Die Erweiterung:

public static Uri WithQuery(this Uri uri, object values)
{
    if (uri == null)
        throw new ArgumentNullException(nameof(uri));

    if (values != null)
    {
        var query = string.Join(
            "&", from p in ParseQueryValues(values)
                 where !string.IsNullOrWhiteSpace(p.Key)
                 let k = HttpUtility.UrlEncode(p.Key.Trim())
                 let v = HttpUtility.UrlEncode(p.Value)
                 orderby k
                 select string.IsNullOrEmpty(v) ? k : $"{k}={v}");

        if (query.Length != 0 || uri.Query.Length != 0)
            uri = new UriBuilder(uri) { Query = query }.Uri;
    }

    return uri;
}

Der Abfrageparser:

private static IEnumerable<KeyValuePair<string, string>> ParseQueryValues(object values)
{
    // Check if a name/value collection.
    var nvc = values as NameValueCollection;
    if (nvc != null)
        return from key in nvc.AllKeys
               from val in nvc.GetValues(key)
               select new KeyValuePair<string, string>(key, val);

    // Check if a string/string dictionary.
    var ssd = values as IEnumerable<KeyValuePair<string, string>>;
    if (ssd != null)
        return ssd;

    // Check if a string/object dictionary.
    var sod = values as IEnumerable<KeyValuePair<string, object>>;
    if (sod == null)
    {
        // Check if a non-generic dictionary.
        var ngd = values as IDictionary;
        if (ngd != null)
            sod = ngd.Cast<dynamic>().ToDictionary<dynamic, string, object>(
                p => p.Key.ToString(), p => p.Value as object);

        // Convert object properties to dictionary.
        if (sod == null)
            sod = new RouteValueDictionary(values);
    }

    // Normalize and return the values.
    return from pair in sod
           from val in pair.Value as IEnumerable<string>
            ?? new[] { pair.Value?.ToString() }
           select new KeyValuePair<string, string>(pair.Key, val);
}

Hier sind die Tests:

var uri = new Uri("https://stackoverflow.com/yo?oldKey=oldValue");

// Test with a string/string dictionary.
var q = uri.WithQuery(new Dictionary<string, string>
{
    ["k1"] = string.Empty,
    ["k2"] = null,
    ["k3"] = "v3"
});

Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?k1&k2&k3=v3"));

// Test with a string/object dictionary.
q = uri.WithQuery(new Dictionary<string, object>
{
    ["k1"] = "v1",
    ["k2"] = new[] { "v2a", "v2b" },
    ["k3"] = null
});

Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?k1=v1&k2=v2a&k2=v2b&k3"));

// Test with a name/value collection.
var nvc = new NameValueCollection()
{
    ["k1"] = string.Empty,
    ["k2"] = "v2a"
};

nvc.Add("k2", "v2b");

q = uri.WithQuery(nvc);
Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?k1&k2=v2a&k2=v2b"));

// Test with any dictionary.
q = uri.WithQuery(new Dictionary<int, HashSet<string>>
{
    [1] = new HashSet<string> { "v1" },
    [2] = new HashSet<string> { "v2a", "v2b" },
    [3] = null
});

Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?1=v1&2=v2a&2=v2b&3"));

// Test with an anonymous object.
q = uri.WithQuery(new
{
    k1 = "v1",
    k2 = new[] { "v2a", "v2b" },
    k3 = new List<string> { "v3" },
    k4 = true,
    k5 = null as Queue<string>
});

Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?k1=v1&k2=v2a&k2=v2b&k3=v3&k4=True&k5"));

// Keep existing query using a name/value collection.
nvc = HttpUtility.ParseQueryString(uri.Query);
nvc.Add("newKey", "newValue");

q = uri.WithQuery(nvc);
Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?newKey=newValue&oldKey=oldValue"));

// Merge two query objects using the RouteValueDictionary.
var an1 = new { k1 = "v1" };
var an2 = new { k2 = "v2" };

q = uri.WithQuery(
    new RouteValueDictionary(an1).Concat(
        new RouteValueDictionary(an2)));

Debug.Assert(q == new Uri(
    "https://stackoverflow.com/yo?k1=v1&k2=v2"));

2

Verkettbare Wrapper-Klasse für HttpValueCollection:

namespace System.Web.Mvc {
    public class QueryStringBuilder {
        private NameValueCollection collection;
        public QueryStringBuilder() {
            collection = System.Web.HttpUtility.ParseQueryString(string.Empty);
        }
        public QueryStringBuilder Add(string key, string value) {
            collection.Add(key, value);
            return this;
        }
        public QueryStringBuilder Remove(string key) {
            collection.Remove(key);
            return this;
        }
        public string this[string key] {
            get { return collection[key]; }
            set { collection[key] = value; }
        }
        public string ToString() {
            return collection.ToString();
        }
    }
}

Anwendungsbeispiel:

QueryStringBuilder parameters = new QueryStringBuilder()
    .Add("view", ViewBag.PageView)
    .Add("page", ViewBag.PageNumber)
    .Add("size", ViewBag.PageSize);
string queryString = parameters.ToString();

1

Ich habe meiner PageBase-Klasse die folgende Methode hinzugefügt.

protected void Redirect(string url)
    {
        Response.Redirect(url);
    }
protected void Redirect(string url, NameValueCollection querystrings)
    {
        StringBuilder redirectUrl = new StringBuilder(url);

        if (querystrings != null)
        {
            for (int index = 0; index < querystrings.Count; index++)
            {
                if (index == 0)
                {
                    redirectUrl.Append("?");
                }

                redirectUrl.Append(querystrings.Keys[index]);
                redirectUrl.Append("=");
                redirectUrl.Append(HttpUtility.UrlEncode(querystrings[index]));

                if (index < querystrings.Count - 1)
                {
                    redirectUrl.Append("&");
                }
            }
        }

        this.Redirect(redirectUrl.ToString());
    }

Anrufen:

NameValueCollection querystrings = new NameValueCollection();    
querystrings.Add("language", "en");
querystrings.Add("id", "134");
this.Redirect("http://www.mypage.com", querystrings);

1

Ich habe einige Erweiterungsmethoden geschrieben, die ich bei der Arbeit mit QueryStrings als sehr nützlich empfunden habe. Oft möchte ich mit dem aktuellen QueryString beginnen und ihn ändern, bevor ich ihn verwende. Etwas wie,

var res = Request.QueryString.Duplicate()
  .ChangeField("field1", "somevalue")
  .ChangeField("field2", "only if following is true", true)
  .ChangeField("id", id, id>0)
  .WriteLocalPathWithQuery(Request.Url)); //Uses context to write the path

Weitere Informationen und die Quelle: http://www.charlesrcook.com/archive/2008/07/23/c-extension-methods-for-asp.net-query-string-operations.aspx

Es ist einfach, aber ich mag den Stil.


1

Ich wollte nur meine 2 Cent einwerfen:

public static class HttpClientExt
{
    public static Uri AddQueryParams(this Uri uri, string query)
    {
        var ub = new UriBuilder(uri);
        ub.Query = string.IsNullOrEmpty(uri.Query) ? query : string.Join("&", uri.Query.Substring(1), query);
        return ub.Uri;
    }

    public static Uri AddQueryParams(this Uri uri, IEnumerable<string> query)
    {
        return uri.AddQueryParams(string.Join("&", query));
    } 

    public static Uri AddQueryParams(this Uri uri, string key, string value)
    {
        return uri.AddQueryParams(string.Join("=", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value)));
    }

    public static Uri AddQueryParams(this Uri uri, params KeyValuePair<string,string>[] kvps)
    {
        return uri.AddQueryParams(kvps.Select(kvp => string.Join("=", HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value))));
    }

    public static Uri AddQueryParams(this Uri uri, IDictionary<string, string> kvps)
    {
        return uri.AddQueryParams(kvps.Select(kvp => string.Join("=", HttpUtility.UrlEncode(kvp.Key), HttpUtility.UrlEncode(kvp.Value))));
    }

    public static Uri AddQueryParams(this Uri uri, NameValueCollection nvc)
    {
        return uri.AddQueryParams(nvc.AllKeys.SelectMany(nvc.GetValues, (key, value) => string.Join("=", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(value))));
    }
}

Die Dokumente sagen, dass uri.Querymit einem beginnen wird? wenn es nicht leer ist, und Sie sollten es abschneiden, wenn Sie es ändern möchten.

Beachten Sie, dass HttpUtility.UrlEncodein gefunden wird System.Web.

Verwendungszweck:

var uri = new Uri("https://api.del.icio.us/v1/posts/suggest").AddQueryParam("url","http://stackoverflow.com")

1

Obwohl ich nicht elegant bin, habe ich mich für eine einfachere Version entschieden, die nicht verwendet wird NameValueCollecitons- nur ein Builder-Muster, das umwickelt ist StringBuilder.

public class UrlBuilder
{
    #region Variables / Properties

    private readonly StringBuilder _builder;

    #endregion Variables / Properties

    #region Constructor

    public UrlBuilder(string urlBase)
    {
        _builder = new StringBuilder(urlBase);
    }

    #endregion Constructor

    #region Methods

    public UrlBuilder AppendParameter(string paramName, string value)
    {
        if (_builder.ToString().Contains("?"))
            _builder.Append("&");
        else
            _builder.Append("?");

        _builder.Append(HttpUtility.UrlEncode(paramName));
        _builder.Append("=");
        _builder.Append(HttpUtility.UrlEncode(value));

        return this;
    }

    public override string ToString()
    {
        return _builder.ToString();
    }

    #endregion Methods
}

Gemäß den vorhandenen Antworten habe ich darauf geachtet, HttpUtility.UrlEncodeAnrufe zu verwenden . Es wird so verwendet:

string url = new UrlBuilder("http://www.somedomain.com/")
             .AppendParameter("a", "true")
             .AppendParameter("b", "muffin")
             .AppendParameter("c", "muffin button")
             .ToString();
// Result: http://www.somedomain.com?a=true&b=muffin&c=muffin%20button

1
// USAGE
[TestMethod]
public void TestUrlBuilder()
{
    Console.WriteLine(
        new UrlBuilder("http://www.google.com?A=B")
            .AddPath("SomePathName")
            .AddPath("AnotherPathName")
            .SetQuery("SomeQueryKey", "SomeQueryValue")
            .AlterQuery("A", x => x + "C"));
}

Ausgabe:

http://www.google.com/SomePathName/AnotherPathName?A=BC&SomeQueryKey=SomeQueryValue

Der Code; ihr könnt mir alle irgendwie irgendwo danken: D.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

// By Demetris Leptos
namespace TheOperator.Foundation.Web
{
    public class UrlBuilder
    {
        public string Scheme { get; set; }

        public string Host { get; set; }

        public int? Port { get; set; }

        public List<string> Paths { get; set; }

        public SortedDictionary<string, string> QueryPairs { get; set; }

        public UrlBuilder(string url)
        {
            this.Paths = new List<string>();
            this.QueryPairs = new SortedDictionary<string, string>();

            string path = null;
            string query = null;
            Uri relativeUri = null;
            if (!Uri.TryCreate(url, UriKind.Relative, out relativeUri))
            {
                var uriBuilder = new UriBuilder(url);
                this.Scheme = uriBuilder.Scheme;
                this.Host = uriBuilder.Host;
                this.Port = uriBuilder.Port;
                path = uriBuilder.Path;
                query = uriBuilder.Query;
            }
            else
            {
                var queryIndex = url.IndexOf('?');
                if (queryIndex >= 0)
                {
                    path = url.Substring(0, queryIndex);
                    query = url.Substring(queryIndex + 1);
                }
                else
                {
                    path = url;
                }
            }
            this.Paths.AddRange(path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries));
            if (query != null)
            {
                var queryKeyValuePairs = HttpUtility.ParseQueryString(query);
                foreach (var queryKey in queryKeyValuePairs.AllKeys)
                {
                    this.QueryPairs[queryKey] = queryKeyValuePairs[queryKey];
                }
            }
        }

        public UrlBuilder AddPath(string value)
        {
            this.Paths.Add(value);
            return this;
        }

        public UrlBuilder SetQuery(string key, string value)
        {
            this.QueryPairs[key] = value;
            return this;
        }

        public UrlBuilder RemoveQuery(string key)
        {
            this.QueryPairs.Remove(key);
            return this;
        }

        public UrlBuilder AlterQuery(string key, Func<string, string> alterMethod, bool removeOnNull = false)
        {
            string value;
            this.QueryPairs.TryGetValue(key, out value);
            value = alterMethod(value);
            if (removeOnNull && value == null)
            {
                return this.RemoveQuery(key);
            }
            else
            {
                return this.SetQuery(key, value);
            }
        }

        public override string ToString()
        {
            var path = !string.IsNullOrWhiteSpace(this.Host)
                ? string.Join("/", this.Host, string.Join("/", this.Paths))
                : string.Join("/", this.Paths);
            var query = string.Join("&", this.QueryPairs.Select(x => string.Concat(x.Key, "=", HttpUtility.UrlEncode(x.Value))));
            return string.Concat(
                !string.IsNullOrWhiteSpace(this.Scheme) ? string.Concat(this.Scheme, "://") : null,
                path,
                !string.IsNullOrWhiteSpace(query) ? string.Concat("?", query) : null);
        }
    }
}

1

Ich habe mich für die von DSO vorgeschlagene Lösung entschieden (beantwortet am 2. August 11 um 7:29 Uhr). Für seine Lösung muss HttpUtility nicht verwendet werden. Gemäß einem Artikel in Dotnetpearls ist die Verwendung eines Wörterbuchs jedoch schneller (in Bezug auf die Leistung) als die Verwendung von NameValueCollection. Hier ist die Lösung von DSO geändert, um Dictionary anstelle von NameValueCollection zu verwenden.

    public static Dictionary<string, string> QueryParametersDictionary()
    {
        var dictionary = new Dictionary<string, string>();
        dictionary.Add("name", "John Doe");
        dictionary.Add("address.city", "Seattle");
        dictionary.Add("address.state_code", "WA");
        dictionary.Add("api_key", "5352345263456345635");

        return dictionary;
    }

    public static string ToQueryString(Dictionary<string, string> nvc)
    {
        StringBuilder sb = new StringBuilder();

        bool first = true;

        foreach (KeyValuePair<string, string> pair in nvc)
        {
                if (!first)
                {
                    sb.Append("&");
                }

                sb.AppendFormat("{0}={1}", Uri.EscapeDataString(pair.Key), Uri.EscapeDataString(pair.Value));

                first = false;
        }

        return sb.ToString();
    }

1

Die Abfragezeichenfolge kann einer URL hinzugefügt werden durch:

  1. Erstellen Sie ein Namenswert-Erfassungsobjekt
  2. Fügen Sie diesem Objekt die Abfragezeichenfolgenelemente und ihre Werte hinzu
  3. Codieren Sie dieses Namenswert-Erfassungsobjekt in die URL, die der Code unter dem folgenden Link bereitstellt

https://blog.codingnovice.com/blog

public ActionResult Create()
{
    //declaring name value collection object
    NameValueCollection collection = new NameValueCollection();

    //adding new value to the name value collection object
    collection.Add("Id1", "wwe323");
    collection.Add("Id2", "454w");
    collection.Add("Id3", "tyt5656");
    collection.Add("Id4", "343wdsd");

    //generating query string
    string url = GenerateQueryString(collection);

    return View();
}

private string GenerateQueryString(NameValueCollection collection)
{
    var querystring = (
        from key in collection.AllKeys
        from value in collection.GetValues(key)
        select string.Format("{0}={1}",
            HttpUtility.UrlEncode(key),
            HttpUtility.UrlEncode(value))
    ).ToArray();
    return "?" + string.Join("&", querystring);
}

0

Ich habe einen Helfer für mein Rasiermesserprojekt geschrieben, indem ich einige der Hinweise aus anderen Antworten verwendet habe.

Das ParseQueryString-Geschäft ist erforderlich, da wir das QueryString-Objekt der aktuellen Anforderung nicht manipulieren dürfen.

@helper GetQueryStringWithValue(string key, string value) {
    var queryString = System.Web.HttpUtility.ParseQueryString(HttpContext.Current.Request.QueryString.ToString());
    queryString[key] = value;
    @Html.Raw(queryString.ToString())
}

Ich benutze es so:

location.search = '?@Helpers.GetQueryStringWithValue("var-name", "var-value")';

Wenn Sie möchten, dass es mehr als einen Wert annimmt, ändern Sie einfach die Parameter in ein Wörterbuch und fügen Sie die Paare zur Abfragezeichenfolge hinzu.


0

Der folgende Code wird aus der HttpValueCollectionImplementierung von ToStringüber ILSpy entfernt, wodurch Sie einen Querystring für Name = Wert erhalten.

Leider ist HttpValueCollection eine interne Klasse, die Sie nur dann zurückerhalten, wenn Sie sie verwenden HttpUtility.ParseQueryString(). Ich habe alle Viewstate-Teile entfernt und es wird standardmäßig codiert:

public static class HttpExtensions
{
    public static string ToQueryString(this NameValueCollection collection)
    {
        // This is based off the NameValueCollection.ToString() implementation
        int count = collection.Count;
        if (count == 0)
            return string.Empty;

        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 0; i < count; i++)
        {
            string text = collection.GetKey(i);
            text = HttpUtility.UrlEncodeUnicode(text);
            string value = (text != null) ? (text + "=") : string.Empty;
            string[] values = collection.GetValues(i);
            if (stringBuilder.Length > 0)
            {
                stringBuilder.Append('&');
            }
            if (values == null || values.Length == 0)
            {
                stringBuilder.Append(value);
            }
            else
            {
                if (values.Length == 1)
                {
                    stringBuilder.Append(value);
                    string text2 = values[0];
                    text2 = HttpUtility.UrlEncodeUnicode(text2);
                    stringBuilder.Append(text2);
                }
                else
                {
                    for (int j = 0; j < values.Length; j++)
                    {
                        if (j > 0)
                        {
                            stringBuilder.Append('&');
                        }
                        stringBuilder.Append(value);
                        string text2 = values[j];
                        text2 = HttpUtility.UrlEncodeUnicode(text2);
                        stringBuilder.Append(text2);
                    }
                }
            }
        }

        return stringBuilder.ToString();
    }
}

0

Dies ist identisch mit der akzeptierten Antwort, außer dass sie etwas kompakter ist:

private string ToQueryString(NameValueCollection nvc)
{
    return "?" + string.Join("&", nvc.AllKeys.Select(k => string.Format("{0}={1}", 
        HttpUtility.UrlEncode(k), 
        HttpUtility.UrlEncode(nvc[k]))));
}

0

Nur für diejenigen, die die VB.NET-Version der Top-Antwort benötigen:

Public Function ToQueryString(nvc As System.Collections.Specialized.NameValueCollection) As String
    Dim array As String() = nvc.AllKeys.SelectMany(Function(key As String) nvc.GetValues(key), Function(key As String, value As String) String.Format("{0}={1}", System.Web.HttpUtility.UrlEncode(key), System.Web.HttpUtility.UrlEncode(value))).ToArray()
    Return "?" + String.Join("&", array)
End Function

Und die Version ohne LINQ:

Public Function ToQueryString(nvc As System.Collections.Specialized.NameValueCollection) As String
    Dim lsParams As New List(Of String)()

    For Each strKey As String In nvc.AllKeys
        Dim astrValue As String() = nvc.GetValues(strKey)

        For Each strValue As String In astrValue
            lsParams.Add(String.Format("{0}={1}", System.Web.HttpUtility.UrlEncode(strKey), System.Web.HttpUtility.UrlEncode(strValue)))
        Next ' Next strValue
    Next ' strKey
    Dim astrParams As String() = lsParams.ToArray()
    lsParams.Clear()
    lsParams = Nothing

    Return "?" + String.Join("&", astrParams)
End Function ' ToQueryString

Und die C # -Version ohne LINQ:

    public static string ToQueryString(System.Collections.Specialized.NameValueCollection nvc)
    {
        List<string> lsParams = new List<string>();

        foreach (string strKey in nvc.AllKeys)
        {
            string[] astrValue = nvc.GetValues(strKey);

            foreach (string strValue in astrValue)
            {
                lsParams.Add(string.Format("{0}={1}", System.Web.HttpUtility.UrlEncode(strKey), System.Web.HttpUtility.UrlEncode(strValue)));
            } // Next strValue

        } // Next strKey

        string[] astrParams =lsParams.ToArray();
        lsParams.Clear();
        lsParams = null;

        return "?" + string.Join("&", astrParams);
    } // End Function ToQueryString
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.