Encodage d'URL à l'aide de C #


340

J'ai une application qui envoie une demande POST au logiciel de forum VB et connecte quelqu'un (sans paramétrer les cookies ou quoi que ce soit).

Une fois l'utilisateur connecté, je crée une variable qui crée un chemin sur sa machine locale.

c: \ dossier temporaire \ date \ nom d'utilisateur

Le problème est que certains noms d'utilisateur lèvent l'exception "caractères illégaux". Par exemple, si mon nom d'utilisateur était, mas|fenixil déclencherait une exception.

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

Je ne veux pas le supprimer de la chaîne, mais un dossier avec leur nom d'utilisateur est créé via FTP sur un serveur. Et cela m'amène à ma deuxième question. Si je crée un dossier sur le serveur, puis-je laisser les "caractères illégaux" dans? Je ne pose cette question que parce que le serveur est basé sur Linux, et je ne sais pas si Linux l'accepte ou non.

EDIT: Il semble que le codage URL n'est PAS ce que je veux .. Voici ce que je veux faire:

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

Où% xx est la valeur ASCII ou toute autre valeur qui identifierait facilement le caractère.


Incorporez-le pour rendre les noms de dossier sûrs du système de fichiers: http://stackoverflow.com/questions/333175/is-there-a-way-of-making-strings-file-path-safe-in-c
missaghi

Réponses:


191

Edit: Notez que cette réponse est désormais obsolète. Voir la réponse de Siarhei Kuchuk ci-dessous pour une meilleure solution

UrlEncoding fera ce que vous proposez ici. Avec C #, vous utilisez simplement HttpUtility, comme mentionné.

Vous pouvez également Regex les caractères illégaux puis les remplacer, mais cela devient beaucoup plus complexe, car vous devrez avoir une certaine forme de machine d'état (commutateur ... cas, par exemple) pour remplacer par les bons caractères. Comme UrlEncodecela se fait d'avance, c'est plutôt facile.

En ce qui concerne Linux par rapport à Windows, certains caractères acceptables sous Linux ne le sont pas, mais je ne m'inquiéterais pas à ce sujet, car le nom du dossier peut être renvoyé en décodant la chaîne Url, en utilisant UrlDecode, afin que vous puissiez aller-retour le changements.


5
cette réponse est désormais obsolète. lisez quelques réponses ci-dessous - à partir de .net45, cela pourrait être la bonne solution: msdn.microsoft.com/en-us/library/…
blueberryfields

1
Pour FTP, chaque partie Uri (nom de dossier ou de fichier) peut être construite en utilisant Uri.EscapeDataString (fileOrFolderName) permettant tous les caractères non compatibles Uri (espaces, unicode ...). Par exemple, pour autoriser tout caractère dans le nom de fichier, utilisez: req = (FtpWebRequest) WebRequest.Create (new Uri (path + "/" + Uri.EscapeDataString (filename))); À l'aide de HttpUtility.UrlEncode (), remplacez les espaces par des signes plus (+). Un comportement correct pour les moteurs de recherche mais incorrect pour les noms de fichiers / dossiers.
Renaud Bancel

asp.net bloque la majorité de xss dans l'url lorsque vous recevez un avertissement lorsque vous essayez d'ajouter un script js A potentially dangerous Request.Path value was detected from the client.
Apprentissage le

511

J'ai expérimenté les différentes méthodes que .NET fournit pour le codage d'URL. Peut-être que le tableau suivant sera utile (en tant que sortie d'une application de test que j'ai écrite):

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]

Les colonnes représentent les encodages comme suit:

  • UrlEncoded: HttpUtility.UrlEncode

  • UrlEncodedUnicode: HttpUtility.UrlEncodeUnicode

  • UrlPathEncoded: HttpUtility.UrlPathEncode

  • EscapedDataString: Uri.EscapeDataString

  • EscapedUriString: Uri.EscapeUriString

  • HtmlEncoded: HttpUtility.HtmlEncode

  • HtmlAttributeEncoded: HttpUtility.HtmlAttributeEncode

  • HexEscaped: Uri.HexEscape

REMARQUES:

  1. HexEscapene peut gérer que les 255 premiers caractères. Par conséquent, il lève une ArgumentOutOfRangeexception pour les caractères latins A étendus (par exemple, Ā).

  2. Ce tableau a été généré dans .NET 4.0 (voir le commentaire de Levi Botelho ci-dessous qui dit que l'encodage dans .NET 4.5 est légèrement différent).

ÉDITER:

J'ai ajouté une deuxième table avec les encodages pour .NET 4.5. Voir cette réponse: https://stackoverflow.com/a/21771206/216440

EDIT 2:

Puisque les gens semblent apprécier ces tables, j'ai pensé que vous pourriez aimer le code source qui génère la table, afin que vous puissiez jouer autour de vous. Il s'agit d'une simple application console C #, qui peut cibler soit .NET 4.0 soit 4.5:

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();
            }
        }
    }
}

2
Ceci est une réponse fantastique. Il s'avère que je voulais utiliser Uri.EscapeDataString et ne pas inclure System.Web. Merci pour ce tableau.
Seravy

7
Notez que ce n'est plus exact à 100%. Certaines fonctions ont légèrement changé entre .NET 4 et .NET 4.5. Voir stackoverflow.com/q/20003106/1068266 .
Levi Botelho

2
@Levi: Merci pour l'avertissement. J'ai ajouté une deuxième réponse avec le tableau pour .NET 4.5. J'ai modifié la réponse d'origine pour créer un lien vers le deuxième tableau.
Simon Tewsi

Notez que la documentation .NET indique Ne pas utiliser; destiné uniquement à la compatibilité du navigateur. Utilisez UrlEncode. , mais cette méthode code de nombreux autres caractères indésirables. Le plus proche est Uri.EscapeUriString, mais attention, il ne prend pas en charge un nullargument.
Andrew

1
J'ai oublié de mentionner, mon commentaire ci-dessus est pour UrlPathEncode. Remplacez donc UrlPathEncodepar Uri.EscapeUriString.
Andrew

279

Vous devez encoder uniquement le nom d'utilisateur ou une autre partie de l'URL qui pourrait être invalide. L'URL encodant une URL peut entraîner des problèmes car quelque chose comme ceci:

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

Rendra

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

Cela ne fonctionnera évidemment pas bien. Au lieu de cela, vous devez encoder UNIQUEMENT la valeur de la paire clé / valeur dans la chaîne de requête, comme ceci:

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

J'espère que cela aide. De plus, comme l' a mentionné teedyay , vous devrez toujours vous assurer que les caractères de nom de fichier illégaux sont supprimés, sinon le système de fichiers n'aimera pas le chemin.


34
L'utilisation de la méthode HttpUtility.UrlPathEncode devrait empêcher le problème que vous décrivez ici.
vipirtti

12
@DJ Pirtu: Il est vrai que UrlPathEncode n'effectuera pas ces changements indésirables dans le chemin, mais il ne codera pas non plus après ?(car il suppose que la chaîne de requête est déjà encodée). Dans l'exemple de Dan Herbert, il semble qu'il prétend que Examplele texte nécessite un encodage, donc HttpUtility.UrlPathEncode("http://www.google.com/search?q=Example");cela ne fonctionnera pas. Essayez-le avec ?q=Ex&ple(où le résultat souhaité est ?q=Ex%26ple). Cela ne fonctionnera pas car (1) UrlPathEncode ne touche plus à rien après ?, et (2) UrlPathEncode n'encode pas de &toute façon.
Tim Goodman

1
Voir ici: connect.microsoft.com/VisualStudio/feedback/details/551839/… Je dois ajouter que bien sûr, il est bon que UrlPathEncode ne code pas &, car vous en avez besoin pour délimiter les paramètres de votre chaîne de requête. Mais il y a des moments où vous voulez aussi des esperluettes codées.
Tim Goodman

10
HttpUtility est remplacé par WebUtility dans les dernières versions, gagnez du temps :)
Wiseman

190

La meilleure façon est d'utiliser

Uri.EscapeUriString

pour ne pas référencer le profil complet de .net 4.


1
Tout à fait d'accord car souvent le "Profil client" est suffisant pour les applications utilisant System.Net mais pas System.Web ;-)
hfrmobile

6
OP parle de vérifier la compatibilité du système de fichiers, donc cela ne fonctionnera pas. Le jeu de caractères non autorisé de Windows est '["/", "\\", "<", ">", ":", "\" "," | ","? "," * "]' Mais beaucoup d'entre eux ne pas être encodé en utilisant EscapedUriString (voir le tableau ci-dessous - merci pour ce tableau @Simon Tewsi) ... "crée un chemin sur leur machine locale" -OP UrlEncoded s'occupe de presque tous les problèmes, mais ne résout pas le problème avec "%" ou "% 3f" dans l'entrée d'origine, car un "décodage" sera désormais différent de l'original.
m1m1k

6
juste pour être clair: CETTE réponse NE FONCTIONNERA PAS pour les systèmes de fichiers
m1m1k

1
De plus, à partir de .NET Framework 4.5, le profil client a été interrompu et seul le package redistribuable complet est disponible.
twomm

29
stackoverflow.com/a/34189188/3436164 Utilisez Uri.EscapeDataStringPAS Uri.EscapeUriStringLisez ce commentaire, cela m'a aidé.
ykadaru

181

Depuis .NET Framework 4.5 et .NET Standard 1.0, vous devez utiliser WebUtility.UrlEncode. Avantages par rapport aux alternatives:

  1. Il fait partie de .NET Framework 4.5+, .NET Core 1.0+, .NET Standard 1.0+, UWP 10.0+ et de toutes les plates-formes Xamarin. HttpUtility, tout en étant disponible dans .NET Framework plus tôt (.NET Framework 1.1+), devient disponible sur d'autres plateformes beaucoup plus tard (.NET Core 2.0+, .NET Standard 2.0+) et il n'est toujours pas disponible dans UWP (voir la question connexe ).

  2. Dans .NET Framework, il réside dansSystem.dll , il ne nécessite donc pas de références supplémentaires, contrairement à HttpUtility.

  3. Il échappe correctement les caractères pour les URL , contrairement à Uri.EscapeUriString(voir les commentaires de la réponse de drweb86 ).

  4. Il n'a pas de limite sur la longueur de la chaîne , contrairement à Uri.EscapeDataString(voir question connexe ), il peut donc être utilisé pour les requêtes POST, par exemple.


J'aime la façon dont il encode en utilisant "+" au lieu de% 20 pour les espaces .. mais celui-ci ne supprime toujours pas "de l'URL et me donne une URL invalide ... eh bien .. je vais juste avoir à faire aa remplacer (" "" "", "")
Piotr Kula

85

Levi Botelho a indiqué que le tableau des encodages précédemment généré n'est plus précis pour .NET 4.5, car les encodages ont légèrement changé entre .NET 4.0 et 4.5. J'ai donc régénéré la table pour .NET 4.5:

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]

Les colonnes représentent les encodages comme suit:

  • 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

REMARQUES:

  1. HexEscape ne peut gérer que les 255 premiers caractères. Par conséquent, il lève une exception ArgumentOutOfRange pour les caractères latins A étendus (par exemple, Ā).

  2. Ce tableau a été généré dans .NET 4.5 (voir la réponse https://stackoverflow.com/a/11236038/216440 pour les encodages pertinents pour .NET 4.0 et ci-dessous).

ÉDITER:

  1. À la suite de la réponse de Discord, j'ai ajouté les nouvelles méthodes WebUtility UrlEncode et HtmlEncode, qui ont été introduites dans .NET 4.5.

2
Non, pas l'utilisateur UrlPathEncode - même le MSDN dit qu'il ne doit pas être utilisé. Il a été construit pour résoudre un problème avec netscape 2 msdn.microsoft.com/en-us/library/…
Jeff

Server.URLEncode est-il encore une autre variante de ce thème? Génère-t-il une sortie différente?
ALEXintlsos

2
@ALEX: dans ASP.NET, l'objet serveur est une instance de HttpServerUtility. En utilisant le décompilateur dotPeek, j'ai jeté un coup d'œil à HttpServerUtility.UrlEncode. Il appelle simplement HttpUtility.UrlEncode afin que la sortie des deux méthodes soit identique.
Simon Tewsi

Il semble que, même avec cette surabondance de méthodes d'encodage, elles échouent toutes de façon assez spectaculaire pour tout ce qui est supérieur à Latin-1, comme → ou ☠. (UrlEncodedUnicode semble au moins essayer de prendre en charge Unicode, mais est obsolète / manquant.)
brianary

Simon, pouvez-vous simplement intégrer cette réponse dans la réponse acceptée? ce sera bien de l'avoir en une seule réponse. vous pouvez l'intégrer et créer un en-tête h1 au bas de cette réponse, ou l'intégrer dans un tableau et marquer des lignes différentes, comme: (Net4.0) ? %3f................................ (Net4.5) ? %3f ..................................
T.Todua

60

L'encodage d'URL est facile dans .NET. Utilisation:

System.Web.HttpUtility.UrlEncode(string url)

Si cela va être décodé pour obtenir le nom du dossier, vous devrez toujours exclure les caractères qui ne peuvent pas être utilisés dans les noms de dossier (*,?, /, Etc.)


Encode-t-il chaque caractère qui ne fait pas partie de l'alphabet?
masfenix

1
Le codage d'URL convertit les caractères non autorisés dans une URL en équivalents entité-caractère. Liste des caractères dangereux: blooberry.com/indexdot/html/topics/urlencoding.htm
Ian Robinson


11
C'est une bonne pratique de mettre l'intégralité de System.Web ... dans votre réponse, cela fait gagner beaucoup de temps à beaucoup de gens :) merci
Liam

3
C'est dangereux: tous les caractères de l'url ne doivent pas être encodés, seules les valeurs des paramètres de la chaîne de requête. La façon dont vous proposez codera également le & qui est nécessaire pour créer plusieurs paramètres dans la chaîne de requête. La soution est de coder chaque valeur des paramètres si nécessaire
Marco Staffoli

12

Si vous ne voyez pas System.Web, modifiez les paramètres de votre projet. Le cadre cible doit être ".NET Framework 4" au lieu de ".NET Framework 4 Client Profile"


1
À mon avis, les développeurs devraient connaître les «profils .NET» et ils devraient utiliser le bon à leurs fins! Il n'est pas très intelligent d'ajouter simplement le profil complet pour obtenir (par exemple System.Web) sans vraiment savoir pourquoi ils ajoutent le profil complet. Utilisez "Profil client" pour vos applications clientes et le profil complet uniquement lorsque cela est nécessaire (par exemple, un client WinForms ou WPF doit utiliser le profil client et non le profil complet)! Par exemple, je ne vois aucune raison d'utiliser HttpServerUtility dans une application cliente ^^ ... si cela est nécessaire, il y a quelque chose qui ne va pas dans la conception de l'application!
hfrmobile

4
Vraiment? Vous ne voyez jamais le besoin d'une application cliente pour construire une URL? Que faites-vous dans la vie - tâches de conciergerie?
sproketboy

@hfrmobile: non. Tout va mal avec le modèle de profil (qui n'a vécu qu'une seule fois et a été abandonné dans la prochaine version). Et c'était évident dès le début. C'est évident pour toi maintenant? Pensez d'abord, n'acceptez pas tout «tel quel» ce que msft essaie de vous vendre; P
abatishchev

Désolé, mais je n'ai jamais dit qu'un client n'a jamais à créer / utiliser une URL. Tant que .NET 4.0 est utilisé, l'utilisateur doit s'en soucier. Pour faire court: les développeurs devraient réfléchir à deux fois avant d'ajouter HttpServerUtility à un client. Il existe d'autres / meilleurs moyens, voyez simplement la réponse avec 139 votes ou "Depuis .NET Framework 4.5, vous pouvez utiliser WebUtility.UrlEncode. Tout d'abord, il réside dans System.dll, donc il ne nécessite aucune référence supplémentaire.".
hfrmobile

9

L'implémentation .NET de UrlEncoden'est pas conforme à la RFC 3986.

  1. Certains caractères ne sont pas codés mais devraient l'être. Les !()*caractères sont répertoriés dans la section 2.2 du RFC en tant que caractères réservés qui doivent être codés mais .NET ne parvient pas à coder ces caractères.

  2. Certains caractères sont encodés mais ne devraient pas l'être. Les .-_caractères ne sont pas répertoriés dans la section 2.2 de la RFC en tant que caractère réservé qui ne doit pas encore être codé .NET code à tort ces caractères.

  3. Le RFC spécifie que pour être cohérent, les implémentations doivent utiliser HEXDIG en majuscules, où .NET produit HEXDIG en minuscules.


4

Je pense que les gens ici ont été détournés par le message UrlEncode. L'URLEncoding n'est pas ce que vous voulez - vous voulez encoder des choses qui ne fonctionneront pas comme nom de fichier sur le système cible.

En supposant que vous vouliez une généralité - n'hésitez pas à trouver les caractères illégaux sur plusieurs systèmes (MacOS, Windows, Linux et Unix), réunissez-les pour former un ensemble de caractères à échapper.

Quant à l'évasion, un HexEscape devrait être bien (Remplacement des caractères par% XX). Convertissez chaque caractère en octets UTF-8 et encodez tout> 128 si vous souhaitez prendre en charge les systèmes qui ne font pas unicode. Mais il existe d'autres moyens, tels que l'utilisation de barres obliques inverses "\" ou d'encodage HTML "" ". Vous pouvez créer le vôtre. Tout système doit tout simplement" coder "le caractère incompatible. Les systèmes ci-dessus vous permettent de recréer le nom d'origine - mais quelque chose comme remplacer les mauvais caractères par des espaces fonctionne également.

Sur la même tangente que ci-dessus, la seule à utiliser est

Uri.EscapeDataString

- Il code tout ce qui est nécessaire pour OAuth, il ne code pas les choses que OAuth interdit de coder, et code l'espace en% 20 et non + (également dans la spécification OATH) Voir: RFC 3986. AFAIK, c'est le dernière spécification d'URI.


3

J'ai écrit une méthode C # qui encode tous les symboles par URL:

    /// <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();
    }

1

Idéalement, ceux-ci iraient dans une classe appelée "FileNaming" ou peut-être simplement renommer Encode en "FileNameEncode". Remarque: ceux-ci ne sont pas conçus pour gérer les chemins d'accès complets, uniquement les noms de dossier et / ou de fichier. Idéalement, vous diviseriez ("/") votre chemin complet en premier, puis vérifieriez les morceaux. Et évidemment, au lieu d'une union, vous pouvez simplement ajouter le caractère "%" à ​​la liste des caractères non autorisés dans Windows, mais je pense que c'est plus utile / lisible / factuel de cette façon. Decode () est exactement le même mais commute le Replace (Uri.HexEscape (s [0]), s) "échappé" avec le caractère.

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;
    }

Merci @ simon-tewsi pour le tableau très utile ci-dessus!


également utile: Path.GetInvalidFileNameChars()
m1m1k

Oui. Voici une façon de procéder: foreach (char c dans System.IO.Path.GetInvalidFileNameChars ()) {filename = filename.Replace (c, '_'); }
netfed le

0

En plus de la réponse de @Dan Herbert, vous nous devriez encoder uniquement les valeurs en général.

Split a le paramètre params Split ('&', '='); expression d'abord divisée par & puis '=' donc les éléments impairs sont toutes les valeurs à encoder indiquées ci-dessous.

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);
        }
    }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.