Antworten:
Verwenden Sie EscapeDataString
immer (für weitere Informationen darüber , warum finden Livven Antwort unten)
Bearbeiten : Dead Link entfernt, wie sich die beiden bei der Codierung unterscheiden
URLEncode
zu auch).
Ich fand die vorhandenen Antworten nicht zufriedenstellend und beschloss, etwas tiefer zu graben, um dieses Problem zu lösen. Überraschenderweise ist die Antwort sehr einfach:
Es gibt (fast *) keinen gültigen Grund, jemals zu verwenden Uri.EscapeUriString
. Wenn Sie eine Zeichenfolge prozentual codieren müssen, verwenden Sie immer Uri.EscapeDataString
.
* Einen gültigen Anwendungsfall finden Sie im letzten Absatz.
Warum ist das? Laut Dokumentation :
Verwenden Sie die EscapeUriString-Methode, um eine nicht entkoppelte URI-Zeichenfolge als Parameter für den Uri-Konstruktor vorzubereiten.
Das macht eigentlich keinen Sinn. Nach RFC 2396 :
Ein URI liegt immer in einer "Escape" -Form vor, da das Escape- oder Deescaping eines abgeschlossenen URI seine Semantik ändern kann.
Während der zitierte RFC durch RFC 3986 überholt wurde , bleibt der Punkt bestehen. Lassen Sie es uns anhand einiger konkreter Beispiele überprüfen:
Sie haben eine einfache URI wie folgt:
http://example.org/
Uri.EscapeUriString
wird es nicht ändern.
Sie beschließen, die Abfragezeichenfolge manuell zu bearbeiten, ohne Rücksicht auf das Escapezeichen zu nehmen:
http://example.org/?key=two words
Uri.EscapeUriString
wird (richtig) dem Raum für Sie entkommen:
http://example.org/?key=two%20words
Sie beschließen, die Abfragezeichenfolge noch weiter manuell zu bearbeiten:
http://example.org/?parameter=father&son
Diese Zeichenfolge wird jedoch nicht von geändert Uri.EscapeUriString
, da davon ausgegangen wird , dass das kaufmännische Und den Beginn eines anderen Schlüssel-Wert-Paares bedeutet. Dies kann oder kann nicht das sein, was Sie beabsichtigt haben.
Sie entscheiden, dass der key
Parameter tatsächlich sein soll father&son
, und korrigieren die vorherige URL manuell, indem Sie das kaufmännische Und maskieren:
http://example.org/?parameter=father%26son
Allerdings Uri.EscapeUriString
entweicht auch das Prozentzeichen, zu einer doppelten Codierung führt:
http://example.org/?parameter=father%2526son
Wie Sie sehen können, ist die Verwendung Uri.EscapeUriString
für den beabsichtigten Zweck die Verwendung &
als Teil eines Schlüssels oder Werts in einer Abfragezeichenfolge anstelle eines Trennzeichens zwischen mehreren Schlüssel-Wert-Paaren unmöglich .
Dies liegt daran, dass bei dem Versuch, es für das Escaping vollständiger URIs geeignet zu machen, reservierte Zeichen ignoriert werden und nur Zeichen maskiert werden, die weder reserviert noch nicht reserviert sind, was übrigens der Dokumentation widerspricht . Auf diese Weise erhalten Sie nicht so etwas wie http%3A%2F%2Fexample.org%2F
, sondern die oben dargestellten Probleme.
Wenn Ihr URI gültig ist, muss er nicht maskiert werden, um als Parameter an den Uri-Construtor übergeben zu werden. Wenn er nicht gültig ist, Uri.EscapeUriString
ist das Aufrufen auch keine magische Lösung. Eigentlich wird es in vielen, wenn nicht den meisten Fällen funktionieren, aber es ist keineswegs zuverlässig.
Sie sollten Ihre URLs und Abfragezeichenfolgen immer erstellen, indem Sie die Schlüssel-Wert-Paare und die Prozentcodierung erfassen und sie dann mit den erforderlichen Trennzeichen verketten. Sie können dies Uri.EscapeDataString
für diesen Zweck verwenden, jedoch nicht Uri.EscapeUriString
, da reservierte Zeichen, wie oben erwähnt, nicht ausgeblendet werden.
Nur wenn Sie dies nicht können, z. B. beim Umgang mit vom Benutzer bereitgestellten URIs, ist die Verwendung Uri.EscapeUriString
als letztes Mittel sinnvoll . Es gelten jedoch die zuvor genannten Einschränkungen. Wenn der vom Benutzer bereitgestellte URI nicht eindeutig ist, sind die Ergebnisse möglicherweise nicht wünschenswert.
encodeURI
/ Uri.EscapeUriString
wird nicht so oft benötigt wie encodeURIComponent
/ Uri.EscapeDataString
(seit wann deaktivieren Sie mit blinden URLs, die in einem Uri-Kontext verwendet werden müssen), aber das bedeutet nicht, dass es seinen Platz nicht hat.
Die Pluszeichen (+) können viel über den Unterschied zwischen diesen Methoden verraten. In einer einfachen URI bedeutet das Pluszeichen "Leerzeichen". Fragen Sie Google nach "happy cat" ab:
Das ist eine gültige URI (probieren Sie es aus) und EscapeUriString
wird sie nicht ändern.
Fragen Sie nun Google nach "happy c ++" ab:
Das ist eine gültige URI (probieren Sie es aus), aber es wird eine Suche nach "happy c" erstellt, da die beiden Pluspunkte als Leerzeichen interpretiert werden. Um dies zu beheben, können wir "happy c ++" an EscapeDataString
und voila * übergeben :
*) Die codierte Datenzeichenfolge ist tatsächlich "happy% 20c% 2B% 2B"; % 20 ist hexadezimal für das Leerzeichen und% 2B ist hexadezimal für das Pluszeichen.
Wenn Sie verwenden, UriBuilder
wie Sie sollten, müssen Sie nur EscapeDataString
einige der Komponenten Ihrer gesamten URI ordnungsgemäß maskieren. @ Livvens Antwort auf diese Frage beweist weiter, dass es wirklich keinen Grund gibt, sie zu verwenden EscapeUriString
.
"https://www.google.com/?q=happy c++"
. Sieht so aus, als müsste ich manuell auf "?" Teilen, oder gibt es einen besseren Weg?
EscapeDataString
. Wenn die von Ihnen angegebene URL die tatsächliche URL ist, möchten Sie diese einfach aufteilen ?
.
Kommentare in der Quelle sprechen den Unterschied deutlich an. Warum diese Informationen nicht über XML-Dokumentationskommentare übermittelt werden, ist mir ein Rätsel.
EscapeUriString:
Diese Methode entgeht jedem Zeichen, das kein reserviertes oder nicht reserviertes Zeichen ist, einschließlich Prozentzeichen. Beachten Sie, dass EscapeUriString auch nicht einem # -Zeichen entgeht.
EscapeDataString:
Diese Methode entgeht jedem Zeichen, das kein nicht reserviertes Zeichen ist, einschließlich Prozentzeichen.
Der Unterschied besteht also darin, wie sie mit reservierten Zeichen umgehen . EscapeDataString
entkommt ihnen; EscapeUriString
nicht.
Laut RFC sind die reservierten Zeichen::/?#[]@!$&'()*+,;=
Der Vollständigkeit halber sind die nicht reservierten Zeichen alphanumerisch und -._~
Beide Methoden entkommen Zeichen, die weder reserviert noch nicht reserviert sind.
Ich bin nicht einverstanden mit der allgemeinen Vorstellung, dass EscapeUriString
es böse ist. Ich denke, eine Methode, die nur illegalen Zeichen (wie Leerzeichen) und nicht reservierten Zeichen entgeht, ist nützlich. Aber es hat eine Eigenart, wie es mit dem %
Charakter umgeht . Prozentcodierte Zeichen ( %
gefolgt von 2 hexadezimalen Ziffern) sind in einer URI zulässig . Ich denke, es EscapeUriString
wäre weitaus nützlicher, wenn es dieses Muster erkennen und die Codierung vermeiden würde, %
wenn es sofort mit 2 Hexadezimalstellen fortfährt.
Ein einfaches Beispiel
var data = "example.com/abc?DEF=あいう\x20えお";
Console.WriteLine(Uri.EscapeUriString(data));
Console.WriteLine(Uri.EscapeDataString(data));
Console.WriteLine(System.Net.WebUtility.UrlEncode(data));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(data));
/*
=>
example.com/abc?DEF=%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86+%E3%81%88%E3%81%8A
example.com%2fabc%3fDEF%3d%e3%81%82%e3%81%84%e3%81%86+%e3%81%88%e3%81%8a
*/
Uri.EscapeDataString()
, wie in der Antwort von @ Livven erläutert. Bei anderen Ansätzen verfügt das System einfach nicht über genügend Informationen, um das beabsichtigte Ergebnis für jede mögliche Eingabe zu erzielen.