468 Stimmen

URL-Kodierung mit C#

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 Rechner erstellt.

c: \tempfolder\date\username

Das Problem ist, dass einige Benutzernamen eine "Illegal chars"-Ausnahme auslösen. Zum Beispiel, wenn mein Benutzername war mas|fenix würde es eine Ausnahme auslösen.

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

Ich möchte sie nicht aus dem String entfernen, aber ein Ordner mit ihrem Benutzernamen wird per FTP auf einem Server erstellt. Und das führt zu meiner zweiten Frage. Wenn ich einen Ordner auf dem Server erstelle, kann ich dann die "illegalen Zeichen" drin lassen? Ich frage das nur, weil der Server auf Linux basiert und ich mir nicht sicher bin, ob Linux das akzeptiert oder nicht.

EDIT: Es scheint, dass die URL-Kodierung nicht das ist, was ich will Hier ist, was ich tun möchte:

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

Dabei ist %xx der ASCII-Wert oder ein anderer Wert, mit dem das Zeichen leicht identifiziert werden kann.

729voto

Simon Tewsi Punkte 15527

Ich habe mit den verschiedenen Methoden experimentiert, die .NET für die URL-Kodierung bietet. Vielleicht wird die folgende Tabelle nützlich sein (als Ausgabe von einer Testanwendung, die ich schrieb):

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

A         %c4%80     %u0100            %c4%80         %C4%80            %C4%80           A           A                    [OoR]
a         %c4%81     %u0101            %c4%81         %C4%81            %C4%81           a           a                    [OoR]
E         %c4%92     %u0112            %c4%92         %C4%92            %C4%92           E           E                    [OoR]
e         %c4%93     %u0113            %c4%93         %C4%93            %C4%93           e           e                    [OoR]
I         %c4%aa     %u012a            %c4%aa         %C4%AA            %C4%AA           I           I                    [OoR]
i         %c4%ab     %u012b            %c4%ab         %C4%AB            %C4%AB           i           i                    [OoR]
O         %c5%8c     %u014c            %c5%8c         %C5%8C            %C5%8C           O           O                    [OoR]
o         %c5%8d     %u014d            %c5%8d         %C5%8D            %C5%8D           o           o                    [OoR]
U         %c5%aa     %u016a            %c5%aa         %C5%AA            %C5%AA           U           U                    [OoR]
u         %c5%ab     %u016b            %c5%ab         %C5%AB            %C5%AB           u           u                    [OoR]

Die Spalten stellen die folgenden Kodierungen 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. HexEscape kann nur die ersten 255 Zeichen verarbeiten. Daher wirft es ein ArgumentOutOfRange Ausnahme für die lateinischen A-erweiterten Zeichen (z.B. A).

  2. Diese Tabelle wurde in .NET 4.0 erstellt (siehe den Kommentar von Levi Botelho weiter unten, der besagt, dass die Kodierung in .NET 4.5 etwas anders ist).

EDITAR:

Ich habe eine zweite Tabelle mit den Kodierungen 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 Sie den Quellcode, mit dem die Tabelle erzeugt wird, vielleicht interessieren könnte, damit Sie selbst damit spielen können. Es handelt sich um eine einfache C#-Konsolenanwendung, die entweder auf .NET 4.0 oder 4.5 ausgerichtet ist:

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" + " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + "AaEeIiOoUu";

            // Need to set the console encoding to display non-ASCII characters correctly (eg the 
            //  Latin A-Extended characters such as AaEe...).
            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();
            }
        }
    }
}

Klicken Sie hier, um den Code auf dotnetfiddle.net auszuführen

333voto

Dan Herbert Punkte 94074

Sie sollten nur den Benutzernamen oder andere Teile der URL kodieren, die ungültig sein könnten. Die URL-Kodierung einer URL kann zu Problemen führen, da sie etwa so aussieht:

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

Wird nachgeben

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

Das wird natürlich nicht gut funktionieren. Stattdessen sollten Sie NUR den Wert des Schlüssel/Wert-Paares im Abfrage-String kodieren, etwa so:

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

Ich hoffe, das hilft. Außerdem, wie teedyay müssen Sie dennoch sicherstellen, dass unzulässige Zeichen im Dateinamen entfernt werden, da das Dateisystem den Pfad sonst nicht akzeptiert.

231voto

Siarhei Kuchuk Punkte 5076

Eine bessere Möglichkeit ist die Verwendung von

Uri.EscapeUriString

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

210voto

Athari Punkte 32497

Seit .NET Framework 4.5 y .NET Standard 1.0 sollten Sie 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 auch allen Xamarin-Plattformen. HttpUtility ist zwar bereits im .NET Framework verfügbar (.NET Framework 1.1+), wird aber auf anderen Plattformen erst viel später verfügbar (.NET Core 2.0+, .NET Standard 2.0+) und ist in UWP noch nicht verfügbar (siehe zugehörige Frage ).

  2. In .NET Framework, es wohnt in System.dll und benötigt daher keine zusätzlichen Referenzen, im Gegensatz zu HttpUtility .

  3. En die Zeichen für URLs richtig umbricht im Gegensatz zu Uri.EscapeUriString (siehe Kommentare zur Antwort von drweb86 ).

  4. En hat keine Beschränkungen für die Länge der Zeichenkette im Gegensatz zu Uri.EscapeDataString (siehe zugehörige Frage ), so dass er z. B. für POST-Anfragen verwendet werden kann.

209voto

Gregory A Beamer Punkte 16670

Edit: Beachten Sie, dass diese Antwort nicht mehr aktuell ist. Siehe Siarhei Kuchuks Antwort unten für eine bessere Lösung

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

Sie können die unzulässigen Zeichen auch durch Regex ersetzen, aber das ist weitaus komplexer, da Sie eine Art von Zustandsmaschine (z. B. switch ... case) benötigen, um die richtigen Zeichen zu verwenden. Da UrlEncode dies im Voraus tut, ist es ziemlich einfach.

Was Linux im Vergleich zu Windows betrifft, gibt es einige Zeichen, die in Linux akzeptabel sind, in Windows aber nicht, aber ich würde mir darüber keine Sorgen machen, da der Ordnername durch Dekodierung der Url-Zeichenfolge zurückgegeben werden kann, indem man UrlDecode so dass Sie die Änderungen abrunden können.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X