Wie können Sie UrlEncode ohne System.Web verwenden?

310

Ich versuche, eine Windows-Clientanwendung zu schreiben, die eine Website für Daten aufruft. Um die Installation auf ein Minimum zu beschränken, versuche ich, nur DLLs im .NET Framework-Clientprofil zu verwenden . Das Problem ist, dass ich einige Parameter urlEncode muss. Gibt es eine einfache Möglichkeit, dies zu tun, ohne System.Web.dll zu importieren, das nicht Teil des Client-Pofiles ist?

Martin Brown
quelle
Können Sie zeigen, wie Sie den Anruf auf der Website ausführen? Vielleicht kann dort etwas getan werden.
Darin Dimitrov
Wie ruft man aus Neugier eine Website für Daten auf, ohne System.Web zu verwenden?
Patrick McDonald
@Patrick, er benutzt wahrscheinlich WebRequestoder WebClient. Das ist der Grund, warum ich nach diesem bestimmten Code gefragt habe, weil es Dinge gibt, die getan werden können, um Daten ordnungsgemäß mit URL-Codierung zu versehen.
Darin Dimitrov
1
Ich verwende ein System.Net.WebRequest-Objekt. Dann rufe ich GetRequestStream auf und schreibe meine Post-Parameter in den Stream. Ich habe den ContentType auch auf "application / x-www-form-urlencoded" gesetzt.
Martin Brown
1
Dies würde natürlich genauso gut zutreffen, wenn ich eine GET-Anfrage ausführen und die Parameter an die URL anhängen würde.
Martin Brown

Antworten:

317

System.Uri.EscapeUriString() kann bei bestimmten Zeichen problematisch sein, für mich war es ein Zahlen- / Pfund-Zeichen in der Zeichenfolge.

Wenn dies ein Problem für Sie ist, versuchen Sie:

System.Uri.EscapeDataString() //Works excellent with individual values

Hier ist eine SO-Antwort, die den Unterschied erklärt:

Was ist der Unterschied zwischen EscapeUriString und EscapeDataString?

und empfiehlt, Uri.EscapeDataString()in jedem Aspekt zu verwenden.

ToddBFisher
quelle
1
Falsch: blogs.msdn.com/b/yangxind/archive/2006/11/09/… Sie haben Probleme mit Pluszeichen, da diese nicht entschlüsselt werden.
Chris Weber
7
Dieser Blog-Beitrag ist ein bisschen alt und ich habe gerade "Uri Escaped" eine vollständige URL und alle Leerzeichen sind% 20 geworden, also denke ich, dass sie es behoben haben. Ich benutze .Net 4.5.
Rodi
EscapeDataString unterstützt auch keine sehr langen Zeichenfolgen, wenn Sie Daten für eine POST-Operation vorbereiten. stackoverflow.com/questions/6695208/…
Bron Davies
Uri.EscapeUriStringist in der Tat sehr problematisch und sollte nicht verwendet werden, da versucht wird, etwas zu tun (vollständige URIs zu umgehen), das tatsächlich nicht konsequent möglich ist. In dieser Antwort finden Sie eine ausführliche Erklärung.
Livven
Auch ein '' Space Charakter.
Waqas Shabbir
252

In .Net 4.5+ verwenden WebUtility

Nur zur Formatierung sende ich dies als Antwort.

Konnte keine guten Beispiele finden, die sie so vergleichen:

string testString = "http://test# space 123/text?var=val&another=two";
Console.WriteLine("UrlEncode:         " + System.Web.HttpUtility.UrlEncode(testString));
Console.WriteLine("EscapeUriString:   " + Uri.EscapeUriString(testString));
Console.WriteLine("EscapeDataString:  " + Uri.EscapeDataString(testString));
Console.WriteLine("EscapeDataReplace: " + Uri.EscapeDataString(testString).Replace("%20", "+"));

Console.WriteLine("HtmlEncode:        " + System.Web.HttpUtility.HtmlEncode(testString));
Console.WriteLine("UrlPathEncode:     " + System.Web.HttpUtility.UrlPathEncode(testString));

//.Net 4.0+
Console.WriteLine("WebUtility.HtmlEncode: " + WebUtility.HtmlEncode(testString));
//.Net 4.5+
Console.WriteLine("WebUtility.UrlEncode:  " + WebUtility.UrlEncode(testString));

Ausgänge:

UrlEncode:             http%3a%2f%2ftest%23+space+123%2ftext%3fvar%3dval%26another%3dtwo
EscapeUriString:       http://test#%20space%20123/text?var=val&another=two
EscapeDataString:      http%3A%2F%2Ftest%23%20space%20123%2Ftext%3Fvar%3Dval%26another%3Dtwo
EscapeDataReplace:     http%3A%2F%2Ftest%23+space+123%2Ftext%3Fvar%3Dval%26another%3Dtwo

HtmlEncode:            http://test# space 123/text?var=val&another=two
UrlPathEncode:         http://test#%20space%20123/text?var=val&another=two

//.Net 4.0+
WebUtility.HtmlEncode: http://test# space 123/text?var=val&another=two
//.Net 4.5+
WebUtility.UrlEncode:  http%3A%2F%2Ftest%23+space+123%2Ftext%3Fvar%3Dval%26another%3Dtwo

In .Net 4.5+ verwenden WebUtility.UrlEncode

Dies scheint HttpUtility.UrlEncode(vor Version 4.0) für die gebräuchlichsten Zeichen zu replizieren :
Uri.EscapeDataString(testString).Replace("%20", "+").Replace("'", "%27").Replace("~", "%7E")
Hinweis: Es EscapeUriStringwird eine gültige Uri-Zeichenfolge beibehalten , wodurch so viele Klartextzeichen wie möglich verwendet werden.

In dieser Antwort finden Sie eine Tabelle zum Vergleich der verschiedenen Codierungen:
https://stackoverflow.com/a/11236038/555798

Zeilenumbrüche Alle hier aufgeführten (außer HttpUtility.HtmlEncode) werden "\n\r"in %0a%0doder konvertiert%0A%0D

Bitte zögern Sie nicht, dies zu bearbeiten und meiner Testzeichenfolge neue Zeichen hinzuzufügen, oder lassen Sie sie in den Kommentaren und ich werde es bearbeiten.

Thymin
quelle
In meinem Fall hatte ich zu verwenden , EscapeDataStringanstatt EscapeUriStringwie wir kodieren Wagenrücklauf und Zeilenvorschub und diese die aggressivere erforderlich erfolgen durch austretendesEscapeDataString
David O'Meara
1
Weitere Beispiele: Sie können Ihre eigenen Testfälle bereitstellen, wenn Sie möchten. Hier ist ein Beispiel für die Ausführung und die anderen Codierungsmethoden, die Unterschiede zeigen. Dotnetfiddle.net/12IFw1
Maslow
3
WebUtility.UrlEncode () und WebUtility.UrlDecode () sind 4.5+. Sie existieren nicht in 4.0.
Derek Kalweit
Die msdn sagt: "Universal Windows Platform: Verfügbar seit 4.5, .NET Framework: Verfügbar seit 4.0" ...
Thymine
54

Sie können verwenden

Uri.EscapeUriString (siehe http://msdn.microsoft.com/en-us/library/system.uri.escapeuristring.aspx )

Matthew Manela
quelle
Gibt es einen Unterschied zwischen diesem und EscapeDataString?
Martin Brown
3
Sie möchten EscapeUriString verwenden. Der EscapeUriString wird versuchen, die gesamte URL (einschließlich http: // part) zu codieren, während EscapeUriString versteht, welche Teile tatsächlich codiert werden sollten
Matthew Manela
1
Ich verstehe, also würde ich in diesem Fall wahrscheinlich EscapeDataString wollen, da ich möglicherweise eine URL als get-Parameter übergeben möchte. Ich hänge in diesem Fall an eine URL an.
Martin Brown
5
@MatthewManela Ich bin mir ziemlich sicher, dass Ihr Kommentar vom 1. Oktober lauten sollte. The EscapeDataString wird versuchen zu codieren ...
Maslow
Nicht benutzen Uri.EscapeUriString. Es "versteht" nicht, welche Teile codiert werden sollen, es ist nur ein fehlgeleiteter Versuch, etwas zu tun (vollständige URIs zu umgehen), was eigentlich unmöglich konsequent zu tun ist. In dieser Antwort finden Sie eine ausführliche Erklärung.
Livven
20

Die Antworten hier sind sehr gut, aber für mich immer noch unzureichend.

Ich schrieb eine kleine Schleife , die vergleicht Uri.EscapeUriStringmit Uri.EscapeDataStringfür alle Zeichen von 0 bis 255.

HINWEIS: Beide Funktionen verfügen über die integrierte Intelligenz, dass Zeichen über 0x80 zuerst UTF-8-codiert und dann prozentual codiert werden.

Hier ist das Ergebnis:

******* Different *******

'#' -> Uri "#" Data "%23"
'$' -> Uri "$" Data "%24"
'&' -> Uri "&" Data "%26"
'+' -> Uri "+" Data "%2B"
',' -> Uri "," Data "%2C"
'/' -> Uri "/" Data "%2F"
':' -> Uri ":" Data "%3A"
';' -> Uri ";" Data "%3B"
'=' -> Uri "=" Data "%3D"
'?' -> Uri "?" Data "%3F"
'@' -> Uri "@" Data "%40"


******* Not escaped *******

'!' -> Uri "!" Data "!"
''' -> Uri "'" Data "'"
'(' -> Uri "(" Data "("
')' -> Uri ")" Data ")"
'*' -> Uri "*" Data "*"
'-' -> Uri "-" Data "-"
'.' -> Uri "." Data "."
'_' -> Uri "_" Data "_"
'~' -> Uri "~" Data "~"

'0' -> Uri "0" Data "0"
.....
'9' -> Uri "9" Data "9"

'A' -> Uri "A" Data "A"
......
'Z' -> Uri "Z" Data "Z"

'a' -> Uri "a" Data "a"
.....
'z' -> Uri "z" Data "z"

******* UTF 8 *******

.....
'Ò' -> Uri "%C3%92" Data "%C3%92"
'Ó' -> Uri "%C3%93" Data "%C3%93"
'Ô' -> Uri "%C3%94" Data "%C3%94"
'Õ' -> Uri "%C3%95" Data "%C3%95"
'Ö' -> Uri "%C3%96" Data "%C3%96"
.....

EscapeUriStringsoll zum Codieren von URLs verwendet werden, während EscapeDataStringzum Beispiel zum Codieren des Inhalts eines Cookies verwendet werden soll, da Cookie-Daten nicht die reservierten Zeichen '='und enthalten dürfen ';'.

Elmue
quelle
schöne Analyse und Aufschlüsselung hier, sehr hilfreich. Wenn jemand Leistungsbenchmarks hat oder kennt (Vergleich aller drei Methoden), wäre das auch schön zu sehen
Shaun Wilson
Dies ist eine gute Analyse, und Sie sollten sie nicht verwenden Uri.EscapeUriString, da es unmöglich ist, vollständige URIs zu umgehen. In dieser Antwort finden Sie eine ausführliche Erklärung.
Livven
16

Im Clientprofil System.dll ist eine vom Clientprofil verwendbare Version, die System.Net.WebUtility-Klasse, vorhanden. Hier ist der MSDN-Link:

WebUtility

Sprague
quelle
Ich möchte darauf hinweisen, dass auf der Hilfeseite für diese Klasse ausdrücklich angegeben ist: "Bietet Methoden zum Codieren und Decodieren von URLs bei der Verarbeitung von Webanforderungen." es könnte also sein, dass sie die Methoden nicht gut benannten.
James White
Guter Punkt, sagen Sie, warum stimmen Sie nicht einen Bruder ab;) Diese Abwärtsabstimmung verfolgt mich seit 2 Jahren! JK ... aber ehrlich gesagt ist das wahrscheinlich der Grund, warum ich den Link gepostet habe, unglücklicherweise, dass ich einen Reputationshit für Fehler in Microsofts Dokumenten bekomme ...
Sprague
11
Es sieht so aus, als ob UrlEncode und UrlDecode nur in der 4.5-Version von .Net zu WebUtility hinzugefügt wurden.
Martin Brown
8

Hier ist ein Beispiel für das Senden einer POST-Anforderung, die Parameter mithilfe des application/x-www-form-urlencodedInhaltstyps ordnungsgemäß codiert :

using (var client = new WebClient())
{
    var values = new NameValueCollection
    {
        { "param1", "value1" },
        { "param2", "value2" },
    };
    var result = client.UploadValues("http://foo.com", values);
}
Darin Dimitrov
quelle
-3
System.Net.WebUtility.HtmlDecode
user3105093
quelle
Die WebUtility-Klasse bietet Methoden zum Codieren und Decodieren von URLs bei der Verarbeitung von Webanforderungen. Es macht das gleiche wie HttpUtility, aber es ist außerhalb des System.Web-Namespace
Alexandru Aliu
3
Es ist falsch, weil es HtmlDecodes und UrlEncode nicht wie die gestellte Frage. Sogar HtmlEncode wäre falsch, da sich die HTML-Codierung von der URL-Codierung unterscheidet.
Martin Brown