Server.UrlEncode vs. HttpUtility.UrlEncode

177

Gibt es einen Unterschied zwischen Server.UrlEncode und HttpUtility.UrlEncode?

Manu
quelle

Antworten:

133

HttpServerUtility.UrlEncodewird HttpUtility.UrlEncodeintern verwendet. Es gibt keinen spezifischen Unterschied. Der Grund für die Existenz Server.UrlEncodeist die Kompatibilität mit klassischem ASP.

Mehrdad Afshari
quelle
3
Was entkommt. Intern ruft es diese Funktion referenzenource.microsoft.com/#System/net/System/Net/…
Jeff
Für Leser: Bitte schauen Sie sich Joel Mullers Antwort unten an. Dies
Sudhanshu Mishra
264

Ich hatte vorher erhebliche Kopfschmerzen mit diesen Methoden. Ich empfehle Ihnen , jede Variante zu vermeidenUrlEncode und stattdessen zu verwendenUri.EscapeDataString - zumindest hat diese ein verständliches Verhalten.

Mal schauen...

HttpUtility.UrlEncode(" ") == "+" //breaks ASP.NET when used in paths, non-
                                  //standard, undocumented.
Uri.EscapeUriString("a?b=e") == "a?b=e" // makes sense, but rarely what you
                                        // want, since you still need to
                                        // escape special characters yourself

Aber mein persönlicher Favorit muss HttpUtility.UrlPathEncode sein - dieses Ding ist wirklich unverständlich. Es codiert:

  • ==>% 20
  • "100% true" ==> "100 %% 20true" (ok, deine URL ist jetzt kaputt)
  • "test A.aspx # anchor B" ==> "test% 20A.aspx # anchor% 20B "
  • "test A.aspx? hmm # anchor B" ==> "test% 20A.aspx? hmm #anchor B " ( beachten Sie den Unterschied zur vorherigen Escape-Sequenz! )

Es enthält auch die sehr spezifische MSDN-Dokumentation "Codiert den Pfadabschnitt einer URL-Zeichenfolge für eine zuverlässige HTTP-Übertragung vom Webserver zu einem Client." - ohne wirklich zu erklären, was es tut. Es ist weniger wahrscheinlich, dass Sie sich mit einem Uzi in den Fuß schießen ...

Kurz gesagt, bleiben Sie bei Uri.EscapeDataString .

Eamon Nerbonne
quelle
4
Und leider funktioniert das immer noch nicht, wenn HTTP-Anforderungen für einige Webserver ausgeführt werden - Uri.EscapeDataString () codiert nicht "!" oder "'", was sich von der Funktionsweise der meisten Browser-Implementierungen von Escape () unterscheidet ...
Chris R. Donnelly
6
! und 'Zeichen sollen nicht codiert werden; Wenn ein fehlerhafter Webserver dies erfordert, kann dies leicht umgangen werden. Vermeiden Sie die Escape-Funktion von Javascript - sie ist von Natur aus fehlerhaft (zum einen unmöglich zu umrunden). Siehe xkr.us/articles/javascript/encode-compare - aber kurz gesagt; Sie können stattdessen encodeUriComponent () verwenden, das sich ähnlich wie EscapeDataString verhält - es codiert vorhersagbar und reversibel einen String und codiert auch nicht! und 'Zeichen.
Eamon Nerbonne
2
Das ist alt, aber die Frage wurde auf die Titelseite gestoßen, also ... Der Pfadteil einer URL-Zeichenfolge ist der Teil zwischen der Domain und dem? oder # in einer URL.
Powerlord
2
@ Tim: Es könnte mehrere geben ?und wer soll sagen, welche codiert werden sollen und welche als Trennzeichen dienen? Zum Leerzeichen: In beiden Fällen befindet sich das Leerzeichen im Hash, sodass das Vorhandensein oder Fehlen eines Abfragefragments keine Rolle spielen sollte. Und schließlich ist es unentschuldbar, einen Uri wie im zweiten Beispiel mit einem% zu beschädigen. Die UrlPathEncodeMethode ist einfach gegabelt und sollte niemals angewendet werden.
Eamon Nerbonne
1
Ich denke, meine Antwort unter stackoverflow.com/a/13993486/237091 kann ein wenig Licht auf die beabsichtigte Verwendung von UrlEncode / UrlPathEncode werfen.
Scott Stafford
60

Fast 9 Jahre, seit dies zum ersten Mal gefragt wurde, und in der Welt von .NET Core und .NET Standard scheinen WebUtility.UrlEncode (unter System.Net) und Uri.EscapeDataString die häufigsten Optionen für die URL-Codierung zu sein . Nach der beliebtesten Antwort hier und anderswo zu urteilen, scheint Uri.EscapeDataString vorzuziehen zu sein. Aber ist es? Ich habe einige Analysen durchgeführt, um die Unterschiede zu verstehen, und hier ist, was ich mir ausgedacht habe:

Für die URL-Codierung passen Zeichen in eine von drei Kategorien: nicht reserviert (legal in einer URL); reserviert (legal in, hat aber eine besondere Bedeutung, daher möchten Sie es möglicherweise codieren); und alles andere (muss immer verschlüsselt sein).

Laut RFC sind die reservierten Zeichen::/?#[]@!$&'()*+,;=

Und die nicht reservierten Zeichen sind alphanumerisch und -._~

Das Urteil

Uri.EscapeDataString definiert seine Mission klar:% -encode alle reservierten und illegalen Zeichen. WebUtility.UrlEncode ist sowohl in der Definition als auch in der Implementierung mehrdeutig. Seltsamerweise codiert es einige reservierte Zeichen, aber nicht andere (warum Klammern und keine Klammern?), Und seltsamerweise codiert es dieses unschuldig nicht reservierte ~Zeichen.

Daher stimme ich dem beliebten Rat zu: Verwenden Sie nach Möglichkeit Uri.EscapeDataString und verstehen Sie, dass reservierte Zeichen wie /und ?codiert werden. Wenn Sie mit potenziell großen Zeichenfolgen umgehen müssen, insbesondere mit URL-codiertem Formularinhalt, müssen Sie entweder auf WebUtility.UrlEncode zurückgreifen und dessen Macken akzeptieren oder das Problem auf andere Weise umgehen .


EDIT: Ich habe versucht , alle der Macken oben erwähnt zu korrigieren Flurl über die Url.Encode, Url.EncodeIllegalCharactersund Url.Decodestatischen Methoden. Diese befinden sich im Kernpaket (das winzig ist und nicht alle HTTP-Inhalte enthält) oder können von der Quelle kopiert werden. Ich freue mich über Ihre Kommentare / Rückmeldungen zu diesen Themen.


Hier ist der Code, mit dem ich herausgefunden habe, welche Zeichen unterschiedlich codiert sind:

var diffs =
    from i in Enumerable.Range(0, char.MaxValue + 1)
    let c = (char)i
    where !char.IsHighSurrogate(c)
    let diff = new {
        Original = c,
        UrlEncode = WebUtility.UrlEncode(c.ToString()),
        EscapeDataString = Uri.EscapeDataString(c.ToString()),
    }
    where diff.UrlEncode != diff.EscapeDataString
    select diff;

foreach (var diff in diffs)
    Console.WriteLine($"{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");
Todd Menier
quelle
2
Das ist brilliant!
Jorge Aguirre
1
Großartige Arbeit bei der Überprüfung der vorgeschlagenen Lösung für das moderne .net-Framework.
Neowizard
Es sollte erwähnt werden, dass es einige Unterschiede zwischen WebUtility und HttpUtility gibt . WebUtility verwendet Großbuchstaben und HttpUtility Kleinbuchstaben für Hexa-Entitäten. Darüber hinaus war HttpUtility in alten Teilmengenversionen von .NET Framework "Client Profile" nicht enthalten. WebUtility ist in .NET Framework 4.0 verfügbar.
Tibx
28

Denken Sie daran, dass Sie wahrscheinlich keine dieser Methoden anwenden sollten. Die Anti-Cross Site Scripting Library von Microsoft enthält Ersatz für HttpUtility.UrlEncodeund HttpUtility.HtmlEncodedas ist sowohl standardkonformer als auch sicherer. Als Bonus erhalten Sie auch eine JavaScriptEncodeMethode.

Joel Mueller
quelle
Nachdem ich die Dokumentation und die häufig gestellten Fragen unter dem angegebenen Link gelesen habe, glaube ich, dass diese Antwort der beste und sicherste Weg ist, Daten zu verschlüsseln! Vielen Dank für das Teilen!
Sudhanshu Mishra
Der Link funktioniert nicht mehr. Was sind die Ersatzmethoden?
Edward Brey
@ EdwardBrey Dies ist die neueste Version der Anti-Cross-Site-Scripting-Bibliothek: microsoft.com/en-au/download/details.aspx?id=28589
Sudhanshu Mishra
11

Server.UrlEncode () bietet Abwärtskompatibilität mit Classic ASP.

Server.UrlEncode(str);

Ist äquivalent zu:

HttpUtility.UrlEncode(str, Response.ContentEncoding);
CMS
quelle
5

Das gleiche Server.UrlEncode()ruftHttpUtility.UrlEncode()

andleer
quelle