Was ist der Unterschied zwischen EscapeUriString und EscapeDataString?

192

Wenn ich mich nur mit URL-Codierung beschäftige, sollte ich EscapeUriString ?

user496949
quelle
10
Entfliehen Sie immer jedem einzelnen Wert mit 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.
Timo

Antworten:

112

Verwenden Sie EscapeDataStringimmer (für weitere Informationen darüber , warum finden Livven Antwort unten)

Bearbeiten : Dead Link entfernt, wie sich die beiden bei der Codierung unterscheiden

Jcl
quelle
3
Ich bin mir nicht sicher, ob der Link tatsächlich mehr Informationen enthält, da es eher um das Entrinnen als um das Entfliehen geht.
Steven
1
Es ist im Grunde der gleiche Unterschied. Wenn Sie den Artikel tatsächlich lesen, gibt es eine Tabelle in der Mitte, die tatsächlich entweicht (nicht entkommt), um die Unterschiede anzuzeigen (im Vergleich URLEncodezu auch).
Jcl
2
Es ist mir immer noch nicht klar - was ist, wenn ich nicht einem ganzen URI, sondern nur einem Teil davon entkomme - (dh den Daten für einen Abfragezeichenfolgenparameter)? Entkomme ich Daten für den URI oder impliziert EscapeDataString etwas völlig anderes?
BrainSlugs83
4
... hat einige Tests so ausgesehen, als ob ich EscapeDataString für einen URI-Parameter haben möchte. Ich habe mit der Zeichenfolge "I heart C ++" getestet und EscapeUriString hat die "+" - Zeichen nicht codiert, sondern nur unverändert gelassen. EscapeDataString hat sie korrekt in "% 2B" konvertiert.
BrainSlugs83
7
Das ist eine schlechte Antwort. Sie sollten EscapeUriString niemals verwenden, es macht keinen Sinn. Siehe Livvens Antwort unten (und stimme ihr zu).
Brandon Paddock
241

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:

  1. Sie haben eine einfache URI wie folgt:

    http://example.org/

    Uri.EscapeUriString wird es nicht ändern.

  2. 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
  3. 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.

  4. Sie entscheiden, dass der keyParameter 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.EscapeUriStringentweicht auch das Prozentzeichen, zu einer doppelten Codierung führt:

    http://example.org/?parameter=father%2526son

Wie Sie sehen können, ist die Verwendung Uri.EscapeUriStringfü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.EscapeUriStringist 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.EscapeDataStringfü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.EscapeUriStringals 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.

Livven
quelle
4
Wow, danke, dass du dieses Problem endlich geklärt hast. Die beiden vorherigen Antworten waren nicht sehr hilfreich.
EverPresent
3
Genau richtig. EscapeUriString (wie das Standardverhalten von EscapeUrl in Win32) wurde von jemandem erstellt, der URIs nicht verstand oder nicht entkommen konnte. Es ist ein fehlgeleiteter Versuch, etwas zu erstellen, das einen fehlerhaften URI akzeptiert und ihn manchmal in die beabsichtigte Version umwandelt. Aber es hat nicht die Informationen, die es braucht, um dies zuverlässig zu tun. Es wird auch häufig anstelle von EscapeDataString verwendet, was ebenfalls sehr problematisch ist. Ich wünschte, EscapeUriString gäbe es nicht. Jede Verwendung ist falsch.
Brandon Paddock
4
schön erklärt +1 es ist viel besser als akzeptiert Link nur Antwort
Ehsan Sajjad
1
Diese Antwort braucht mehr Aufmerksamkeit. Es ist der richtige Weg, es zu tun. Die anderen Antworten haben Szenarien, in denen sie nicht die beabsichtigten Ergebnisse liefern.
Timo
1
... Sicher encodeURI/ Uri.EscapeUriStringwird 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.
Crescent Fresh
56

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:

https://www.google.com/?q=happy+cat

Das ist eine gültige URI (probieren Sie es aus) und EscapeUriString wird sie nicht ändern.

Fragen Sie nun Google nach "happy c ++" ab:

https://www.google.com/?q=happy+c++

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 EscapeDataStringund voila * übergeben :

https://www.google.com/?q=happy+c%2B%2B

*) 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, UriBuilderwie Sie sollten, müssen Sie nur EscapeDataStringeinige der Komponenten Ihrer gesamten URI ordnungsgemäß maskieren. @ Livvens Antwort auf diese Frage beweist weiter, dass es wirklich keinen Grund gibt, sie zu verwenden EscapeUriString.

Seth
quelle
Vielen Dank. Was ist, wenn Sie eine absolute URI - Zeichenfolge haben , dass Sie zu kodieren müssen, zum Beispiel "https://www.google.com/?q=happy c++". Sieht so aus, als müsste ich manuell auf "?" Teilen, oder gibt es einen besseren Weg?
Wensveen
Wenn Sie die gesamte URL als Parameter an eine andere URL übergeben, verwenden Sie EscapeDataString. Wenn die von Ihnen angegebene URL die tatsächliche URL ist, möchten Sie diese einfach aufteilen ?.
Seth
7

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 . EscapeDataStringentkommt ihnen; EscapeUriStringnicht.

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 EscapeUriStringes 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 EscapeUriStringwäre weitaus nützlicher, wenn es dieses Muster erkennen und die Codierung vermeiden würde, %wenn es sofort mit 2 Hexadezimalstellen fortfährt.

Todd Menier
quelle
1

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
*/
Lernen
quelle