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?
c#
.net
url
query-string
Boas
quelle
quelle
Antworten:
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:
Ich kann mir vorstellen, dass es auch in LINQ eine super elegante Möglichkeit gibt, dies zu tun ...
quelle
application/x-www-form-urlencoded
und tatsächlich durch HTML definiert, um Formulardaten als Teil einerGET
Anforderung 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 demselbenname
Attribut enthält. Siehe goo.gl/uk1AgSie können eine neue beschreibbare Instanz von erstellen,
HttpValueCollection
indem Sie sie aufrufenSystem.Web.HttpUtility.ParseQueryString(string.Empty)
und dann wie eine beliebige verwendenNameValueCollection
. Nachdem Sie die gewünschten Werte hinzugefügt haben, können SieToString
die Sammlung wie folgt aufrufen , um eine Abfragezeichenfolge abzurufen:Das
HttpValueCollection
ist intern und daher können Sie keine Instanz direkt erstellen. Sobald Sie jedoch eine Instanz erhalten haben, können Sie sie wie jede andere verwendenNameValueCollection
. Da das eigentliche Objekt, mit dem Sie arbeiten, ein istHttpValueCollection
, ruft das Aufrufen der ToString-Methode die überschriebene Methode aufHttpValueCollection
, 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.QueryHelpers
Klasse verwenden, was dies erheblich vereinfacht.https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.webutilities.queryhelpers
Beispielcode:
quelle
public static string ToURLQueryString(this IDictionary dict) { ... }
Add
Methode können Sie der Abfragezeichenfolge mehrere Instanzen eines Namens hinzufügen . Das heißt, diequeryString.Add("type", "1"); queryString.Add("type", "2");
Verwendung derAdd
Methode ist wahrscheinlich eine bessere Möglichkeit, dies die ganze Zeit tatsächlich zu tun.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:
Verwendungszweck:
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 derHttpUtility.UrlEncode
Methode anstelle der veraltetenHttpUtility.UrlEncodeUnicode
Methode behandelt.quelle
Ich habe vor einiger Zeit eine ähnliche Frage beantwortet . Grundsätzlich ist es am besten, die Klasse zu verwenden
HttpValueCollection
, dieRequest.QueryString
eigentlich 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.HttpValueCollection
wird erweitertNameValueCollection
und verfügt über einen Konstruktor, der eine codierte Abfragezeichenfolge (einschließlich kaufmännisches Und und Fragezeichen) verwendet und eineToString()
Methode überschreibt , mit der die Abfragezeichenfolge später aus der zugrunde liegenden Auflistung neu erstellt werden kann.Beispiel:
quelle
httpValueCollection.ToString()
ruft tatsächlich an,httpValueCollection.ToString(true)
so dass das Hinzufügen dertrue
Explizität nicht erforderlich ist.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 ).
Bearbeiten: mit Null-Unterstützung, obwohl Sie es wahrscheinlich an Ihre spezielle Situation anpassen müssen
quelle
Flurl [Offenlegung: Ich bin der Autor] unterstützt das Erstellen von Abfragezeichenfolgen über anonyme Objekte (unter anderem):
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:
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
quelle
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;)
Beispiel Verwendung
Ausgabe
quelle
Wie wäre es mit Erweiterungsmethoden, mit denen Sie die Parameter in einem fließenden Stil wie diesem hinzufügen können?
Hier ist die Überladung, die Folgendes verwendet
string
:Und hier ist die Überlastung, die Folgendes verwendet
StringBuilder
:quelle
NameValueCollection
,HttpValueCollection
oder einUri
ersten. Vielen Dank!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.FormUrlEncodedContent
so verwendet:quelle
quelle
.ToArray()
s nicht.Fügen Sie diese Klasse Ihrem Projekt hinzu
Und benutze es so:
quelle
Mein Angebot:
Verwendungszweck:
quelle
Ungetestet, aber ich denke, etwas in dieser Richtung würde ganz gut funktionieren
quelle
Eine auf einer schnellen Erweiterungsmethode basierende Version:
Sie können eine where-Klausel verwenden, um auszuwählen, welche Parameter der Zeichenfolge hinzugefügt werden.
quelle
Angenommen, Sie möchten Abhängigkeiten zu anderen Assemblys reduzieren und die Dinge einfach halten, können Sie Folgendes tun:
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).
quelle
Kombinierte die Top-Antworten, um eine anonyme Objektversion zu erstellen :
Das erzeugt dies:
Hier ist der Code:
quelle
Wie akzeptierte Lösung, jedoch auf "Punkt" -LINQ-Syntax übertragen ...
quelle
Ich habe eine Erweiterungsmethode für Uri , die:
uri.WithQuery(new { name = "value" })
string/string
Paaren (z . B. Dictionary`2 ).string/object
Paaren (z . B. RouteValueDictionary ).Die dokumentierte Version finden Sie hier .
Die Erweiterung:
Der Abfrageparser:
Hier sind die Tests:
quelle
Verkettbare Wrapper-Klasse für HttpValueCollection:
Anwendungsbeispiel:
quelle
Ich habe meiner PageBase-Klasse die folgende Methode hinzugefügt.
Anrufen:
quelle
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,
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.
quelle
Ich wollte nur meine 2 Cent einwerfen:
Die Dokumente sagen, dass
uri.Query
mit einem beginnen wird?
wenn es nicht leer ist, und Sie sollten es abschneiden, wenn Sie es ändern möchten.Beachten Sie, dass
HttpUtility.UrlEncode
in gefunden wirdSystem.Web
.Verwendungszweck:
quelle
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 istStringBuilder
.Gemäß den vorhandenen Antworten habe ich darauf geachtet,
HttpUtility.UrlEncode
Anrufe zu verwenden . Es wird so verwendet:quelle
Ausgabe:
Der Code; ihr könnt mir alle irgendwie irgendwo danken: D.
quelle
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.
quelle
Die Abfragezeichenfolge kann einer URL hinzugefügt werden durch:
https://blog.codingnovice.com/blog
quelle
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.
Ich benutze es so:
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.
quelle
Der folgende Code wird aus der
HttpValueCollection
Implementierung vonToString
ü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:quelle
Dies ist identisch mit der akzeptierten Antwort, außer dass sie etwas kompakter ist:
quelle
Nur für diejenigen, die die VB.NET-Version der Top-Antwort benötigen:
Und die Version ohne LINQ:
Und die C # -Version ohne LINQ:
quelle