URL-Codierung mit C #

340

Ich habe eine Anwendung, die eine POST-Anfrage an die VB-Forensoftware sendet und jemanden anmeldet (ohne Cookies oder ähnliches zu setzen).

Sobald der Benutzer angemeldet ist, erstelle ich eine Variable, die einen Pfad auf seinem lokalen Computer erstellt.

c: \ tempfolder \ date \ username

Das Problem ist, dass einige Benutzernamen die Ausnahme "Illegale Zeichen" auslösen. Wenn mein Benutzername beispielsweise wäre mas|fenix, würde dies eine Ausnahme auslösen.

Path.Combine( _      
  Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData), _
  DateTime.Now.ToString("ddMMyyhhmm") + "-" + form1.username)

Ich möchte es nicht aus der Zeichenfolge entfernen, aber ein Ordner mit ihrem Benutzernamen wird über FTP auf einem Server erstellt. Und das führt zu meiner zweiten Frage. Kann ich beim Erstellen eines Ordners auf dem Server die "unzulässigen Zeichen" belassen? Ich frage dies nur, weil der Server auf Linux basiert und ich nicht sicher bin, ob Linux dies akzeptiert oder nicht.

BEARBEITEN: Es scheint, dass die URL-Codierung NICHT das ist, was ich will. Folgendes möchte ich tun:

old username = mas|fenix
new username = mas%xxfenix

Wobei% xx der ASCII-Wert oder ein anderer Wert ist, der das Zeichen leicht identifizieren würde.

masfenix
quelle
Integrieren Sie dies, um die
Ordnernamen des

Antworten:

191

Bearbeiten: Beachten Sie, dass diese Antwort jetzt veraltet ist. Siehe Siarhei Kuchuks Antwort unten für eine bessere Lösung

UrlEncoding macht das, was Sie hier vorschlagen. Mit C # verwenden Sie einfach HttpUtility, wie erwähnt.

Sie können die unzulässigen Zeichen auch neu formulieren und dann ersetzen. Dies wird jedoch weitaus komplexer, da Sie eine Art Zustandsmaschine (z. B. Schalter ... Fall) benötigen, um sie durch die richtigen Zeichen zu ersetzen. Da UrlEncodedies im Vorfeld geschieht, ist es ziemlich einfach.

Was Linux im Vergleich zu Windows betrifft, gibt es einige Zeichen, die unter Linux akzeptabel sind und nicht unter Windows, aber ich würde mir darüber keine Sorgen machen, da der Ordnername durch Dekodieren der URL-Zeichenfolge mit zurückgegeben werden kann UrlDecode, sodass Sie die Zeichenfolge umgehen können Änderungen.

Gregory A Beamer
quelle
5
Diese Antwort ist jetzt veraltet. las ein paar Antworten unten - wie von .net45 dieser die richtige Lösung könnte sein: msdn.microsoft.com/en-us/library/...
blueberryfields
1
Für FTP kann jeder Uri-Teil (Ordner- oder Dateiname) mit Uri.EscapeDataString (fileOrFolderName) erstellt werden, wobei alle nicht Uri-kompatiblen Zeichen (Leerzeichen, Unicode ...) zugelassen werden. Verwenden Sie beispielsweise: req = (FtpWebRequest) WebRequest.Create (neuer Uri (Pfad + "/" + Uri.EscapeDataString (Dateiname))), um ein beliebiges Zeichen im Dateinamen zuzulassen. Ersetzen Sie mit HttpUtility.UrlEncode () Leerzeichen durch Pluszeichen (+). Ein korrektes Verhalten für Suchmaschinen, aber falsch für Datei- / Ordnernamen.
Renaud Bancel
asp.net blockiert die meisten xss in der URL, da Sie immer dann gewarnt werden, wenn Sie versuchen, ein js-Skript hinzuzufügen A potentially dangerous Request.Path value was detected from the client.
Lernen
510

Ich habe mit den verschiedenen Methoden experimentiert, die .NET für die URL-Codierung bereitstellt. Vielleicht ist die folgende Tabelle nützlich (als Ausgabe einer von mir geschriebenen Test-App):

Unencoded UrlEncoded UrlEncodedUnicode UrlPathEncoded EscapedDataString EscapedUriString HtmlEncoded HtmlAttributeEncoded HexEscaped
A         A          A                 A              A                 A                A           A                    %41
B         B          B                 B              B                 B                B           B                    %42

a         a          a                 a              a                 a                a           a                    %61
b         b          b                 b              b                 b                b           b                    %62

0         0          0                 0              0                 0                0           0                    %30
1         1          1                 1              1                 1                1           1                    %31

[space]   +          +                 %20            %20               %20              [space]     [space]              %20
!         !          !                 !              !                 !                !           !                    %21
"         %22        %22               "              %22               %22              "      "               %22
#         %23        %23               #              %23               #                #           #                    %23
$         %24        %24               $              %24               $                $           $                    %24
%         %25        %25               %              %25               %25              %           %                    %25
&         %26        %26               &              %26               &                &       &                %26
'         %27        %27               '              '                 '                '       '                %27
(         (          (                 (              (                 (                (           (                    %28
)         )          )                 )              )                 )                )           )                    %29
*         *          *                 *              %2A               *                *           *                    %2A
+         %2b        %2b               +              %2B               +                +           +                    %2B
,         %2c        %2c               ,              %2C               ,                ,           ,                    %2C
-         -          -                 -              -                 -                -           -                    %2D
.         .          .                 .              .                 .                .           .                    %2E
/         %2f        %2f               /              %2F               /                /           /                    %2F
:         %3a        %3a               :              %3A               :                :           :                    %3A
;         %3b        %3b               ;              %3B               ;                ;           ;                    %3B
<         %3c        %3c               <              %3C               %3C              &lt;        &lt;                 %3C
=         %3d        %3d               =              %3D               =                =           =                    %3D
>         %3e        %3e               >              %3E               %3E              &gt;        >                    %3E
?         %3f        %3f               ?              %3F               ?                ?           ?                    %3F
@         %40        %40               @              %40               @                @           @                    %40
[         %5b        %5b               [              %5B               %5B              [           [                    %5B
\         %5c        %5c               \              %5C               %5C              \           \                    %5C
]         %5d        %5d               ]              %5D               %5D              ]           ]                    %5D
^         %5e        %5e               ^              %5E               %5E              ^           ^                    %5E
_         _          _                 _              _                 _                _           _                    %5F
`         %60        %60               `              %60               %60              `           `                    %60
{         %7b        %7b               {              %7B               %7B              {           {                    %7B
|         %7c        %7c               |              %7C               %7C              |           |                    %7C
}         %7d        %7d               }              %7D               %7D              }           }                    %7D
~         %7e        %7e               ~              ~                 ~                ~           ~                    %7E

Ā         %c4%80     %u0100            %c4%80         %C4%80            %C4%80           Ā           Ā                    [OoR]
ā         %c4%81     %u0101            %c4%81         %C4%81            %C4%81           ā           ā                    [OoR]
Ē         %c4%92     %u0112            %c4%92         %C4%92            %C4%92           Ē           Ē                    [OoR]
ē         %c4%93     %u0113            %c4%93         %C4%93            %C4%93           ē           ē                    [OoR]
Ī         %c4%aa     %u012a            %c4%aa         %C4%AA            %C4%AA           Ī           Ī                    [OoR]
ī         %c4%ab     %u012b            %c4%ab         %C4%AB            %C4%AB           ī           ī                    [OoR]
Ō         %c5%8c     %u014c            %c5%8c         %C5%8C            %C5%8C           Ō           Ō                    [OoR]
ō         %c5%8d     %u014d            %c5%8d         %C5%8D            %C5%8D           ō           ō                    [OoR]
Ū         %c5%aa     %u016a            %c5%aa         %C5%AA            %C5%AA           Ū           Ū                    [OoR]
ū         %c5%ab     %u016b            %c5%ab         %C5%AB            %C5%AB           ū           ū                    [OoR]

Die Spalten stellen Codierungen wie folgt dar:

  • UrlEncoded: HttpUtility.UrlEncode

  • UrlEncodedUnicode: HttpUtility.UrlEncodeUnicode

  • UrlPathEncoded: HttpUtility.UrlPathEncode

  • EscapedDataString: Uri.EscapeDataString

  • EscapedUriString: Uri.EscapeUriString

  • HtmlEncoded: HttpUtility.HtmlEncode

  • HtmlAttributeEncoded: HttpUtility.HtmlAttributeEncode

  • HexEscaped: Uri.HexEscape

ANMERKUNGEN:

  1. HexEscapekann nur die ersten 255 Zeichen verarbeiten. Daher wird eine ArgumentOutOfRangeAusnahme für die lateinischen A-Extended-Zeichen (z. B. Ā) ausgelöst.

  2. Diese Tabelle wurde in .NET 4.0 generiert (siehe Levi Botelhos Kommentar unten, der besagt, dass die Codierung in .NET 4.5 etwas anders ist).

BEARBEITEN:

Ich habe eine zweite Tabelle mit den Codierungen für .NET 4.5 hinzugefügt. Siehe diese Antwort: https://stackoverflow.com/a/21771206/216440

EDIT 2:

Da die Leute diese Tabellen zu schätzen scheinen, dachte ich, dass Ihnen der Quellcode, der die Tabelle generiert, gefallen könnte, damit Sie selbst herumspielen können. Es ist eine einfache C # -Konsolenanwendung, die entweder auf .NET 4.0 oder 4.5 abzielen kann:

using System;
using System.Collections.Generic;
using System.Text;
// Need to add a Reference to the System.Web assembly.
using System.Web;

namespace UriEncodingDEMO2
{
    class Program
    {
        static void Main(string[] args)
        {
            EncodeStrings();

            Console.WriteLine();
            Console.WriteLine("Press any key to continue...");
            Console.Read();
        }

        public static void EncodeStrings()
        {
            string stringToEncode = "ABCD" + "abcd"
            + "0123" + " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + "ĀāĒēĪīŌōŪū";

            // Need to set the console encoding to display non-ASCII characters correctly (eg the 
            //  Latin A-Extended characters such as ĀāĒē...).
            Console.OutputEncoding = Encoding.UTF8;

            // Will also need to set the console font (in the console Properties dialog) to a font 
            //  that displays the extended character set correctly.
            // The following fonts all display the extended characters correctly:
            //  Consolas
            //  DejaVu Sana Mono
            //  Lucida Console

            // Also, in the console Properties, set the Screen Buffer Size and the Window Size 
            //  Width properties to at least 140 characters, to display the full width of the 
            //  table that is generated.

            Dictionary<string, Func<string, string>> columnDetails =
                new Dictionary<string, Func<string, string>>();
            columnDetails.Add("Unencoded", (unencodedString => unencodedString));
            columnDetails.Add("UrlEncoded",
                (unencodedString => HttpUtility.UrlEncode(unencodedString)));
            columnDetails.Add("UrlEncodedUnicode",
                (unencodedString => HttpUtility.UrlEncodeUnicode(unencodedString)));
            columnDetails.Add("UrlPathEncoded",
                (unencodedString => HttpUtility.UrlPathEncode(unencodedString)));
            columnDetails.Add("EscapedDataString",
                (unencodedString => Uri.EscapeDataString(unencodedString)));
            columnDetails.Add("EscapedUriString",
                (unencodedString => Uri.EscapeUriString(unencodedString)));
            columnDetails.Add("HtmlEncoded",
                (unencodedString => HttpUtility.HtmlEncode(unencodedString)));
            columnDetails.Add("HtmlAttributeEncoded",
                (unencodedString => HttpUtility.HtmlAttributeEncode(unencodedString)));
            columnDetails.Add("HexEscaped",
                (unencodedString
                    =>
                    {
                        // Uri.HexEscape can only handle the first 255 characters so for the 
                        //  Latin A-Extended characters, such as A, it will throw an 
                        //  ArgumentOutOfRange exception.                       
                        try
                        {
                            return Uri.HexEscape(unencodedString.ToCharArray()[0]);
                        }
                        catch
                        {
                            return "[OoR]";
                        }
                    }));

            char[] charactersToEncode = stringToEncode.ToCharArray();
            string[] stringCharactersToEncode = Array.ConvertAll<char, string>(charactersToEncode,
                (character => character.ToString()));
            DisplayCharacterTable<string>(stringCharactersToEncode, columnDetails);
        }

        private static void DisplayCharacterTable<TUnencoded>(TUnencoded[] unencodedArray,
            Dictionary<string, Func<TUnencoded, string>> mappings)
        {
            foreach (string key in mappings.Keys)
            {
                Console.Write(key.Replace(" ", "[space]") + " ");
            }
            Console.WriteLine();

            foreach (TUnencoded unencodedObject in unencodedArray)
            {
                string stringCharToEncode = unencodedObject.ToString();
                foreach (string columnHeader in mappings.Keys)
                {
                    int columnWidth = columnHeader.Length + 1;
                    Func<TUnencoded, string> encoder = mappings[columnHeader];
                    string encodedString = encoder(unencodedObject);

                    // ASSUMPTION: Column header will always be wider than encoded string.
                    Console.Write(encodedString.Replace(" ", "[space]").PadRight(columnWidth));
                }
                Console.WriteLine();
            }
        }
    }
}
Simon Tewsi
quelle
2
Dies ist eine fantastische Antwort. Es stellte sich heraus, dass ich Uri.EscapeDataString verwenden und System.Web nicht einschließen wollte. Danke für diesen Tisch.
Seravy
7
Beachten Sie, dass dies nicht mehr 100% genau ist. Bestimmte Funktionen haben sich zwischen .NET 4 und .NET 4.5 geringfügig geändert. Siehe stackoverflow.com/q/20003106/1068266 .
Levi Botelho
2
@ Levi: Danke für das Heads Up. Ich habe eine zweite Antwort mit der Tabelle für .NET 4.5 hinzugefügt. Ich habe die ursprüngliche Antwort bearbeitet, um auf die zweite Tabelle zu verlinken.
Simon Tewsi
Beachten Sie, dass in der .NET-Dokumentation "Nicht verwenden" angegeben ist. Nur zur Browserkompatibilität gedacht. Verwenden Sie UrlEncode. , aber diese Methode codiert viele andere unerwünschte Zeichen. Das nächste ist Uri.EscapeUriString, aber Vorsicht, es unterstützt kein nullArgument.
Andrew
1
Ich habe vergessen zu erwähnen, mein Kommentar oben ist für UrlPathEncode. Also im Grunde ersetzen UrlPathEncodemit Uri.EscapeUriString.
Andrew
278

Sie sollten nur den Benutzernamen oder einen anderen Teil der URL codieren, der möglicherweise ungültig ist. Das Codieren einer URL durch URL kann zu Problemen führen, da Folgendes der Fall ist:

string url = HttpUtility.UrlEncode("http://www.google.com/search?q=Example");

Wird nachgeben

http% 3a% 2f% 2fwww.google.com% 2fsearch% 3fq% 3dBeispiel

Dies wird offensichtlich nicht gut funktionieren. Stattdessen sollten Sie NUR den Wert des Schlüssel / Wert-Paares in der Abfragezeichenfolge wie folgt codieren:

string url = "http://www.google.com/search?q=" + HttpUtility.UrlEncode("Example");

Hoffentlich hilft das. Wie bereits erwähnt, müssen Sie außerdem sicherstellen, dass unzulässige Dateinamenzeichen entfernt werden, da sonst das Dateisystem den Pfad nicht mag.

Dan Herbert
quelle
33
Die Verwendung der HttpUtility.UrlPathEncode-Methode sollte das hier beschriebene Problem verhindern.
Vipirtti
12
@DJ Pirtu: Es ist wahr, dass UrlPathEncode diese unerwünschten Änderungen im Pfad nicht vornimmt, aber auch nichts nach dem codiert ?(da davon ausgegangen wird, dass die Abfragezeichenfolge bereits codiert ist). In Dan Herberts Beispiel sieht es so aus, als wäre er Exampleder Text, der codiert werden muss, also HttpUtility.UrlPathEncode("http://www.google.com/search?q=Example");nicht funktioniert. Versuchen Sie es mit ?q=Ex&ple(wo das gewünschte Ergebnis ist ?q=Ex%26ple). Es wird nicht funktionieren, weil (1) UrlPathEncode danach nichts mehr berührt ?und (2) UrlPathEncode &sowieso nicht codiert .
Tim Goodman
1
Siehe hier: connect.microsoft.com/VisualStudio/feedback/details/551839/… Ich sollte hinzufügen, dass es natürlich gut ist, dass UrlPathEncode nicht codiert &, da Sie dies benötigen, um Ihre Abfragezeichenfolgenparameter abzugrenzen. Es gibt jedoch Zeiten, in denen Sie auch codierte kaufmännische Und-Zeichen wünschen.
Tim Goodman
10
HttpUtility wird von WebUtility in den neuesten Versionen gelungen, sparen Sie sich etwas Zeit :)
Wiseman
189

Besser ist es zu benutzen

Uri.EscapeUriString

nicht auf das vollständige Profil von .net verweisen 4.

Siarhei Kuchuk
quelle
1
Stimme voll und ganz zu, da oft das "Kundenprofil" für Apps ausreicht, die System.Net verwenden, aber nicht System.Web verwenden ;-)
hfrmobile
6
OP spricht davon, es auf Dateisystemkompatibilität zu überprüfen, daher funktioniert dies nicht. Windows nicht zugelassener Zeichensatz ist '["/", "\\", "<", ">", ":", "\" "," | ","? "," * "]', Aber viele davon Lassen Sie sich nicht mit EscapedUriString codieren (siehe Tabelle unten - danke für diese Tabelle @Simon Tewsi) ... "erstellt einen Pfad auf ihrem lokalen Computer" -OP UrlEncoded kümmert sich um fast alle Probleme, löst das Problem jedoch nicht Problem mit "%" oder "% 3f" in der ursprünglichen Eingabe, da eine "Dekodierung" jetzt anders als das Original ist.
m1m1k
6
Nur um es klar zu machen: DIESE Antwort FUNKTIONIERT NICHT für Dateisysteme
m1m1k
1
Darüber hinaus wurde das Client-Profil ab .NET Framework 4.5 eingestellt und es ist nur das vollständige weiterverteilbare Paket verfügbar.
Zwei
29
stackoverflow.com/a/34189188/3436164 Verwendung Uri.EscapeDataStringNICHT Uri.EscapeUriStringLesen Sie diesen Kommentar, er hat mir geholfen.
Ykadaru
181

Seit .NET Framework 4.5 und .NET Standard 1.0 sollten Sie verwenden WebUtility.UrlEncode. Vorteile gegenüber Alternativen:

  1. Es ist Teil von .NET Framework 4.5+, .NET Core 1.0+, .NET Standard 1.0+, UWP 10.0+ und allen Xamarin-Plattformen. HttpUtilityWährend es früher in .NET Framework verfügbar war (.NET Framework 1.1+), wird es viel später auf anderen Plattformen verfügbar (.NET Core 2.0+, .NET Standard 2.0+) und ist in UWP immer noch nicht verfügbar (siehe verwandte Frage ).

  2. In .NET Framework befindet es sich inSystem.dll , sodass im Gegensatz zu .NET Framework keine zusätzlichen Referenzen erforderlich sind HttpUtility.

  3. Im Gegensatz zu URLs werden Zeichen für URLs ordnungsgemäß ausgeblendetUri.EscapeUriString (siehe Kommentare zur Antwort von drweb86 ).

  4. Im Gegensatz zu (siehe verwandte Frage ) gibt es keine Begrenzung für die Länge der Zeichenfolge , sodass sie beispielsweise für POST-Anforderungen verwendet werden kann.Uri.EscapeDataString

Athari
quelle
Ich mag die Art und Weise, wie es mit "+" anstelle von% 20 für Leerzeichen codiert. Aber dieses entfernt immer noch nicht "aus der URL und gibt mir eine ungültige URL ... na ja ... ich muss nur aa ersetzen (" "" "", "")
Piotr Kula
84

Levi Botelho bemerkte, dass die zuvor generierte Codierungstabelle für .NET 4.5 nicht mehr korrekt ist, da sich die Codierungen zwischen .NET 4.0 und 4.5 geringfügig geändert haben. Also habe ich die Tabelle für .NET 4.5 neu generiert:

Unencoded UrlEncoded UrlEncodedUnicode UrlPathEncoded WebUtilityUrlEncoded EscapedDataString EscapedUriString HtmlEncoded HtmlAttributeEncoded WebUtilityHtmlEncoded HexEscaped
A         A          A                 A              A                    A                 A                A           A                    A                     %41
B         B          B                 B              B                    B                 B                B           B                    B                     %42

a         a          a                 a              a                    a                 a                a           a                    a                     %61
b         b          b                 b              b                    b                 b                b           b                    b                     %62

0         0          0                 0              0                    0                 0                0           0                    0                     %30
1         1          1                 1              1                    1                 1                1           1                    1                     %31

[space]   +          +                 %20            +                    %20               %20              [space]     [space]              [space]               %20
!         !          !                 !              !                    %21               !                !           !                    !                     %21
"         %22        %22               "              %22                  %22               %22              &quot;      &quot;               &quot;                %22
#         %23        %23               #              %23                  %23               #                #           #                    #                     %23
$         %24        %24               $              %24                  %24               $                $           $                    $                     %24
%         %25        %25               %              %25                  %25               %25              %           %                    %                     %25
&         %26        %26               &              %26                  %26               &                &amp;       &amp;                &amp;                 %26
'         %27        %27               '              %27                  %27               '                &#39;       &#39;                &#39;                 %27
(         (          (                 (              (                    %28               (                (           (                    (                     %28
)         )          )                 )              )                    %29               )                )           )                    )                     %29
*         *          *                 *              *                    %2A               *                *           *                    *                     %2A
+         %2b        %2b               +              %2B                  %2B               +                +           +                    +                     %2B
,         %2c        %2c               ,              %2C                  %2C               ,                ,           ,                    ,                     %2C
-         -          -                 -              -                    -                 -                -           -                    -                     %2D
.         .          .                 .              .                    .                 .                .           .                    .                     %2E
/         %2f        %2f               /              %2F                  %2F               /                /           /                    /                     %2F
:         %3a        %3a               :              %3A                  %3A               :                :           :                    :                     %3A
;         %3b        %3b               ;              %3B                  %3B               ;                ;           ;                    ;                     %3B
<         %3c        %3c               <              %3C                  %3C               %3C              &lt;        &lt;                 &lt;                  %3C
=         %3d        %3d               =              %3D                  %3D               =                =           =                    =                     %3D
>         %3e        %3e               >              %3E                  %3E               %3E              &gt;        >                    &gt;                  %3E
?         %3f        %3f               ?              %3F                  %3F               ?                ?           ?                    ?                     %3F
@         %40        %40               @              %40                  %40               @                @           @                    @                     %40
[         %5b        %5b               [              %5B                  %5B               [                [           [                    [                     %5B
\         %5c        %5c               \              %5C                  %5C               %5C              \           \                    \                     %5C
]         %5d        %5d               ]              %5D                  %5D               ]                ]           ]                    ]                     %5D
^         %5e        %5e               ^              %5E                  %5E               %5E              ^           ^                    ^                     %5E
_         _          _                 _              _                    _                 _                _           _                    _                     %5F
`         %60        %60               `              %60                  %60               %60              `           `                    `                     %60
{         %7b        %7b               {              %7B                  %7B               %7B              {           {                    {                     %7B
|         %7c        %7c               |              %7C                  %7C               %7C              |           |                    |                     %7C
}         %7d        %7d               }              %7D                  %7D               %7D              }           }                    }                     %7D
~         %7e        %7e               ~              %7E                  ~                 ~                ~           ~                    ~                     %7E

Ā         %c4%80     %u0100            %c4%80         %C4%80               %C4%80            %C4%80           Ā           Ā                    Ā                     [OoR]
ā         %c4%81     %u0101            %c4%81         %C4%81               %C4%81            %C4%81           ā           ā                    ā                     [OoR]
Ē         %c4%92     %u0112            %c4%92         %C4%92               %C4%92            %C4%92           Ē           Ē                    Ē                     [OoR]
ē         %c4%93     %u0113            %c4%93         %C4%93               %C4%93            %C4%93           ē           ē                    ē                     [OoR]
Ī         %c4%aa     %u012a            %c4%aa         %C4%AA               %C4%AA            %C4%AA           Ī           Ī                    Ī                     [OoR]
ī         %c4%ab     %u012b            %c4%ab         %C4%AB               %C4%AB            %C4%AB           ī           ī                    ī                     [OoR]
Ō         %c5%8c     %u014c            %c5%8c         %C5%8C               %C5%8C            %C5%8C           Ō           Ō                    Ō                     [OoR]
ō         %c5%8d     %u014d            %c5%8d         %C5%8D               %C5%8D            %C5%8D           ō           ō                    ō                     [OoR]
Ū         %c5%aa     %u016a            %c5%aa         %C5%AA               %C5%AA            %C5%AA           Ū           Ū                    Ū                     [OoR]
ū         %c5%ab     %u016b            %c5%ab         %C5%AB               %C5%AB            %C5%AB           ū           ū                    ū                     [OoR]

Die Spalten stellen Codierungen wie folgt dar:

  • UrlEncoded: HttpUtility.UrlEncode
  • UrlEncodedUnicode: HttpUtility.UrlEncodeUnicode
  • UrlPathEncoded: HttpUtility.UrlPathEncode
  • WebUtilityUrlEncoded: WebUtility.UrlEncode
  • EscapedDataString: Uri.EscapeDataString
  • EscapedUriString: Uri.EscapeUriString
  • HtmlEncoded: HttpUtility.HtmlEncode
  • HtmlAttributeEncoded: HttpUtility.HtmlAttributeEncode
  • WebUtilityHtmlEncoded: WebUtility.HtmlEncode
  • HexEscaped: Uri.HexEscape

ANMERKUNGEN:

  1. HexEscape kann nur die ersten 255 Zeichen verarbeiten. Daher wird eine ArgumentOutOfRange-Ausnahme für die lateinischen A-Extended-Zeichen (z. B. Ā) ausgelöst.

  2. Diese Tabelle wurde in .NET 4.5 generiert (siehe Antwort https://stackoverflow.com/a/11236038/216440 für die für .NET 4.0 und darunter relevanten Codierungen).

BEARBEITEN:

  1. Als Ergebnis der Antwort von Discord habe ich die neuen WebUtility UrlEncode- und HtmlEncode-Methoden hinzugefügt, die in .NET 4.5 eingeführt wurden.
Simon Tewsi
quelle
2
Nein, kein Benutzer UrlPathEncode - selbst der MSDN sagt, dass er nicht verwendet werden soll. Es wurde erstellt, um ein Problem mit netscape 2 zu beheben. Msdn.microsoft.com/en-us/library/…
Jeff
Ist Server.URLEncode eine weitere Variation dieses Themas? Erzeugt es eine andere Ausgabe?
ALEXintlsos
2
@ALEX: In ASP.NET ist das Serverobjekt eine Instanz von HttpServerUtility. Mit dem dotPeek-Dekompiler habe ich mir HttpServerUtility.UrlEncode angesehen. Es wird nur HttpUtility.UrlEncode aufgerufen, sodass die Ausgabe der beiden Methoden identisch ist.
Simon Tewsi
Es scheint, dass trotz dieser Überfülle an Codierungsmethoden alle für alles über Latin-1, wie → oder ☠, immer noch ziemlich spektakulär versagen. (UrlEncodedUnicode scheint zumindest zu versuchen, Unicode zu unterstützen, ist aber veraltet / fehlt.)
Brian
Simon, kannst du diese Antwort einfach in die akzeptierte Antwort integrieren? Es wird schön sein, es in einer Antwort zu haben. Sie könnten es integrieren und eine h1-Überschrift am Ende dieser Antwort machen oder in eine Tabelle integrieren und verschiedene Zeilen markieren, wie: (Net4.0) ? %3f................................ (Net4.5) ? %3f ..................................
T.Todua
60

Die URL-Codierung ist in .NET einfach. Verwenden:

System.Web.HttpUtility.UrlEncode(string url)

Wenn dies dekodiert wird, um den Ordnernamen zu erhalten, müssen Sie weiterhin Zeichen ausschließen, die nicht in Ordnernamen verwendet werden können (*,?, / Usw.).

teedyay
quelle
Codiert es jedes Zeichen, das nicht Teil des Alphabets ist?
Masfenix
1
Die URL-Codierung konvertiert Zeichen, die in einer URL nicht zulässig sind, in Zeichen-Entitäts-Entsprechungen. Liste der unsicheren Zeichen: blooberry.com/indexdot/html/topics/urlencoding.htm
Ian Robinson
MSDN Link auf HttpUtility.UrlEncode: msdn.microsoft.com/en-us/library/4fkewx0t.aspx
Ian Robinson
11
Es ist eine gute Praxis, das vollständige System.Web ... Teil in Ihre Antwort zu setzen, es spart vielen Menschen ein wenig Zeit :) Danke
Liam
3
Dies ist gefährlich: Es müssen nicht alle Zeichen der URL codiert werden, sondern nur die Werte der Parameter von Querystring. Die von Ihnen vorgeschlagene Art und Weise codiert auch das &, das zum Erstellen mehrerer Parameter im Querystring erforderlich ist. Die Lösung besteht darin, jeden Wert der Parameter bei Bedarf zu codieren
Marco Staffoli
12

Wenn Sie System.Web nicht sehen können, ändern Sie Ihre Projekteinstellungen. Das Zielframework sollte ".NET Framework 4" anstelle von ".NET Framework 4-Clientprofil" sein.

nützlich
quelle
1
Meiner Meinung nach sollten Entwickler über ".NET-Profile" Bescheid wissen und das richtige für ihre Zwecke verwenden! Nur das vollständige Profil hinzuzufügen, um (z. B. System.Web) zu erhalten, ohne wirklich zu wissen, warum sie das vollständige Profil hinzufügen, ist nicht sehr klug. Verwenden Sie "Client-Profil" für Ihre Client- Apps und das vollständige Profil nur bei Bedarf (z. B. sollte ein WinForms- oder WPF-Client das Client-Profil und nicht das vollständige Profil verwenden)! zB sehe ich keinen Grund, die HttpServerUtility in einer Client-App zu verwenden ^^ ... wenn dies benötigt wird, stimmt etwas mit dem Design der App nicht!
hfrmobile
4
"Ja wirklich?" Sehen Sie nie eine Notwendigkeit für eine Client-App, um eine URL zu erstellen? Was machst du beruflich - Hausmeisterpflichten?
Sproketboy
@hfrmobile: nein. Es ist alles falsch mit dem Profilmodell (das nur einmal lebte und in der nächsten Version aufgegeben wurde). Und das war von Anfang an klar. Ist es jetzt für dich offensichtlich? Denken Sie zuerst, akzeptieren Sie nicht alles so wie es ist, was msft versucht, Ihnen zu verkaufen; P
abatishchev
Entschuldigung, aber ich habe nie gesagt, dass ein Client niemals eine URL erstellen / verwenden muss. Solange .NET 4.0 verwendet wird, sollte sich der Benutzer darum kümmern. Um es kurz zu machen: Entwickler sollten zweimal überlegen, bevor sie einem Client HttpServerUtility hinzufügen. Es gibt andere / bessere Möglichkeiten, sehen Sie einfach die Antwort mit 139 Stimmen oder "Seit .NET Framework 4.5 können Sie WebUtility.UrlEncode verwenden. Erstens befindet es sich in System.dll, sodass keine zusätzlichen Referenzen erforderlich sind."
hfrmobile
9

Die .NET-Implementierung von UrlEncodeentspricht nicht RFC 3986.

  1. Einige Zeichen sind nicht codiert, sollten es aber sein. Die !()*Zeichen werden in Abschnitt 2.2 des RFC als reservierte Zeichen aufgeführt, die codiert werden müssen, aber .NET kann diese Zeichen nicht codieren.

  2. Einige Zeichen sind codiert, sollten es aber nicht sein. Die .-_Zeichen werden in Abschnitt 2.2 des RFC nicht als reserviertes Zeichen aufgeführt, das noch nicht codiert werden sollte. .NET codiert diese Zeichen fälschlicherweise.

  3. Der RFC gibt an, dass Implementierungen aus Gründen der Konsistenz HEXDIG in Großbuchstaben verwenden sollten, wobei .NET HEXDIG in Kleinbuchstaben erzeugt.

Charlie
quelle
4

Ich denke, die Leute hier wurden von der UrlEncode-Nachricht abgelenkt. URLEncoding ist nicht das, was Sie wollen - Sie möchten Dinge codieren, die auf dem Zielsystem nicht als Dateiname funktionieren.

Angenommen, Sie möchten eine gewisse Allgemeinheit - Sie können die illegalen Zeichen auf mehreren Systemen (MacOS, Windows, Linux und Unix) finden und sie zu einer Reihe von Zeichen zusammenfassen, um zu entkommen.

Für die Flucht sollte ein HexEscape in Ordnung sein (Ersetzen der Zeichen durch% XX). Konvertieren Sie jedes Zeichen in UTF-8-Bytes und codieren Sie alles> 128, wenn Sie Systeme unterstützen möchten, die keinen Unicode ausführen. Es gibt aber auch andere Möglichkeiten, z. B. die Verwendung von Schrägstrichen "\" oder HTML-Codierung "". Sie können Ihre eigenen erstellen. Alles, was ein System tun muss, ist, das nicht kompatible Zeichen zu "codieren". Mit den oben genannten Systemen können Sie das neu erstellen ursprünglicher Name - aber so etwas wie das Ersetzen der schlechten Zeichen durch Leerzeichen funktioniert auch.

Auf der gleichen Tangente wie oben ist die einzige, die verwendet werden kann

Uri.EscapeDataString

- Es codiert alles, was für OAuth benötigt wird, es codiert nicht die Dinge, die OAuth das Codieren verbietet, und codiert den Speicherplatz als% 20 und nicht als + (auch in der OATH-Spezifikation). Siehe: RFC 3986. AFAIK, dies ist das neueste URI-Spezifikation.

Gerard ONeill
quelle
3

Ich habe eine C # -Methode geschrieben, die ALLE Symbole url-codiert:

    /// <summary>
    /// !#$345Hf} → %21%23%24%33%34%35%48%66%7D
    /// </summary>
    public static string UrlEncodeExtended( string value )
    {
        char[] chars = value.ToCharArray();
        StringBuilder encodedValue = new StringBuilder();
        foreach (char c in chars)
        {
            encodedValue.Append( "%" + ( (int)c ).ToString( "X2" ) );
        }
        return encodedValue.ToString();
    }
Sergey
quelle
1

Idealerweise gehören diese zu einer Klasse namens "FileNaming" oder benennen Encode einfach in "FileNameEncode" um. Hinweis: Diese sind nicht für die Verarbeitung vollständiger Pfade ausgelegt, sondern nur für die Ordner- und / oder Dateinamen. Idealerweise würden Sie zuerst Ihren vollständigen Pfad teilen ("/") und dann die Teile überprüfen. Und natürlich könnten Sie anstelle einer Vereinigung einfach das Zeichen "%" zur Liste der Zeichen hinzufügen, die in Windows nicht zulässig sind, aber ich denke, dass dies auf diese Weise hilfreicher / lesbarer / sachlicher ist. Decode () ist genau das gleiche, wechselt jedoch das Ersetzen (Uri.HexEscape (s [0]), s) mit dem Zeichen "maskiert".

public static List<string> urlEncodedCharacters = new List<string>
{
  "/", "\\", "<", ">", ":", "\"", "|", "?", "%" //and others, but not *
};
//Since this is a superset of urlEncodedCharacters, we won't be able to only use UrlEncode() - instead we'll use HexEncode
public static List<string> specialCharactersNotAllowedInWindows = new List<string>
{
  "/", "\\", "<", ">", ":", "\"", "|", "?", "*" //windows dissallowed character set
};

    public static string Encode(string fileName)
    {
        //CheckForFullPath(fileName); // optional: make sure it's not a path?
        List<string> charactersToChange = new List<string>(specialCharactersNotAllowedInWindows);
        charactersToChange.AddRange(urlEncodedCharacters.
            Where(x => !urlEncodedCharacters.Union(specialCharactersNotAllowedInWindows).Contains(x)));   // add any non duplicates (%)

        charactersToChange.ForEach(s => fileName = fileName.Replace(s, Uri.HexEscape(s[0])));   // "?" => "%3f"

        return fileName;
    }

Danke @ simon-tewsi für die sehr nützliche Tabelle oben!

m1m1k
quelle
auch nützlich: Path.GetInvalidFileNameChars()
m1m1k
Ja. Hier ist eine Möglichkeit, dies zu tun: foreach (char c in System.IO.Path.GetInvalidFileNameChars ()) {filename = filename.Replace (c, '_'); }
netfed
0

Zusätzlich zu der Antwort von @Dan Herbert sollten Sie nur die Werte allgemein codieren.

Split hat den Parameter Parameter Split ('&', '='); Ausdruck wird zuerst durch & dann '=' geteilt, so dass ungerade Elemente alle zu codierenden Werte sind (siehe unten).

public static void EncodeQueryString(ref string queryString)
{
    var array=queryString.Split('&','=');
    for (int i = 0; i < array.Length; i++) {
        string part=array[i];
        if(i%2==1)
        {               
            part=System.Web.HttpUtility.UrlEncode(array[i]);
            queryString=queryString.Replace(array[i],part);
        }
    }
}
Davut Gürbüz
quelle