Кодирование URL с использованием C # - PullRequest
297 голосов
/ 22 февраля 2009

У меня есть приложение, которое отправляет запрос POST на программное обеспечение форума VB и регистрирует кого-либо (без установки файлов cookie или чего-либо еще).

Как только пользователь вошел в систему, я создаю переменную, которая создает путь на его локальной машине.

C: \ TempFolder \ дата \ имя пользователя

Проблема в том, что некоторые имена пользователей выдают исключение "Недопустимые символы". Например, если бы мое имя пользователя было mas|fenix, это вызвало бы исключение ..

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

Я не хочу удалять его из строки, но папка с именем пользователя создается через FTP на сервере. И это приводит ко второму вопросу. Если я создаю папку на сервере, могу ли я оставить «незаконные символы» в? Я спрашиваю об этом только потому, что сервер базируется на Linux, и я не уверен, принимает ли Linux это или нет.

РЕДАКТИРОВАТЬ: Кажется, что кодирование URL не то, что я хочу .. Вот что я хочу сделать:

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

Где% xx - это значение ASCII или любое другое значение, которое легко идентифицирует символ.

Ответы [ 13 ]

465 голосов
/ 28 июня 2012

Я экспериментировал с различными методами .NET для кодирования URL. Возможно, будет полезна следующая таблица (как вывод из тестового приложения, которое я написал):

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]

Столбцы представляют следующие кодировки:

  • UrlEncoded: HttpUtility.UrlEncode

  • UrlEncodedUnicode: HttpUtility.UrlEncodeUnicode

  • UrlPathEncoded: HttpUtility.UrlPathEncode

  • EscapedDataString: Uri.EscapeDataString

  • EscapedUriString: Uri.EscapeUriString

  • HtmlEncoded: HttpUtility.HtmlEncode

  • HtmlAttributeEncoded: HttpUtility.HtmlAttributeEncode

  • HexEscaped: Uri.HexEscape

ПРИМЕЧАНИЯ:

  1. HexEscape может обрабатывать только первые 255 символов. Поэтому он генерирует исключение ArgumentOutOfRange для латинских символов A-Extended (например, Ā).

  2. Эта таблица была сгенерирована в .NET 4.0 (см. Комментарий Леви Ботелхо ниже, в котором говорится, что кодировка в .NET 4.5 немного отличается).

EDIT:

Я добавил вторую таблицу с кодировками для .NET 4.5. Смотрите этот ответ: https://stackoverflow.com/a/21771206/216440

РЕДАКТИРОВАТЬ 2:

Поскольку люди, похоже, ценят эти таблицы, я подумал, что вам может понравиться исходный код, который генерирует таблицу, поэтому вы можете поиграть с самим собой. Это простое консольное приложение C #, которое может быть нацелено на .NET 4.0 или 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();
            }
        }
    }
}
265 голосов
/ 23 февраля 2009

Вы должны кодировать только имя пользователя или другую часть URL, которая может быть недействительной. URL-кодировка URL-адреса может привести к проблемам, поскольку что-то вроде этого:

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

даст

HTTP% 3A% 2F% 2fwww.google.com% 2fsearch% 3fq% 3dExample

Это явно не сработает. Вместо этого вы должны кодировать ТОЛЬКО значение пары ключ / значение в строке запроса, например:

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

Надеюсь, это поможет. Кроме того, как упоминалось teedyay , вам все равно нужно будет убедиться, что недопустимые символы имени файла удалены, иначе файловой системе не понравится путь.

176 голосов
/ 22 февраля 2009

Изменить: Обратите внимание, что этот ответ устарел. См. Ответ Сергея Кучука ниже для лучшего исправления

UrlEncoding сделает то, что вы предлагаете здесь. С C # вы просто используете HttpUtility, как уже упоминалось.

Вы также можете повторно проверять недопустимые символы и затем заменять, но это становится намного более сложным, так как вам потребуется некоторая форма конечного автомата (например, switch ... case) для замены правильными символами. Поскольку UrlEncode делает это заранее, это довольно просто.

Что касается Linux по сравнению с Windows, в Linux есть некоторые символы, которые являются приемлемыми, но не Windows, но я не стал бы беспокоиться об этом, поскольку имя папки можно вернуть, расшифровав строку Url, используя UrlDecode так что вы можете в оба конца изменения.

163 голосов
/ 03 июня 2013

Начиная с .NET Framework 4.5 и .NET Standard 1.0 следует использовать WebUtility.UrlEncode. Преимущества перед альтернативами:

  1. Он является частью .NET Framework 4.5+, .NET Core 1.0+, .NET Standard 1.0+, UWP 10.0+ и всех платформ Xamarin. HttpUtility, хотя он и был доступен в .NET Framework ранее (.NET Framework 1.1+), он становится доступным на других платформах гораздо позже (.NET Core 2.0+, .NET Standard 2.0+) и по-прежнему недоступен. в UWP (см. связанный вопрос ).

  2. В .NET Framework он находится в System.dll, поэтому в отличие от HttpUtility.

  3. Это правильно экранирует символы для URL , в отличие от Uri.EscapeUriString (см. комментарии к ответу drweb86 ).

  4. У него нет ограничений на длину строки , в отличие от Uri.EscapeDataString (см. связанный вопрос ), поэтому его можно использовать для запросов POST, например.

163 голосов
/ 15 сентября 2011

Лучше использовать

Uri.EscapeUriString

не ссылаться на полный профиль .net 4.

72 голосов
/ 14 февраля 2014

Леви Ботельхо отметил, что таблица сгенерированных ранее кодировок больше не является точной для .NET 4.5, поскольку кодировки слегка изменились между .NET 4.0 и 4.5. Итак, я восстановил таблицу для .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]

Столбцы представляют следующие кодировки:

  • 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

ПРИМЕЧАНИЯ:

  1. HexEscape может обрабатывать только первые 255 символов. Поэтому он генерирует исключение ArgumentOutOfRange для латинских символов A-Extended (например, Ā).

  2. Эта таблица была сгенерирована в .NET 4.5 (см. Ответ https://stackoverflow.com/a/11236038/216440 для кодировок, относящихся к .NET 4.0 и ниже).

РЕДАКТИРОВАТЬ:

  1. В результате ответа Discord я добавил новые методы WebUtility UrlEncode и HtmlEncode, которые были представлены в .NET 4.5.
54 голосов
/ 22 февраля 2009

Url-кодирование легко в .NET. Использование:

System.Web.HttpUtility.UrlEncode(string url)

Если это будет декодировано, чтобы получить имя папки, вам все равно нужно будет исключить символы, которые нельзя использовать в именах папок (*,?, /, И т. Д.)

12 голосов
/ 20 марта 2011

Если вы не видите System.Web, измените настройки своего проекта. Целевой платформой должно быть ".NET Framework 4" вместо ".NET Framework 4 Client Profile"

9 голосов
/ 22 мая 2013

.NET реализация UrlEncode не соответствует RFC 3986.

  1. Некоторые символы не закодированы, но должны быть. Символы !()* перечислены в разделе 2.2 RFC как зарезервированные символы, которые необходимо кодировать, но .NET не может кодировать эти символы.

  2. Некоторые символы закодированы, но не должны быть. Символы .-_ не перечислены в разделе 2.2 RFC как зарезервированные символы, которые пока не следует кодировать. NET ошибочно кодирует эти символы.

  3. В RFC указывается, что для обеспечения согласованности реализации следует использовать HEXDIG в верхнем регистре, где .NET создает HEXDIG в нижнем регистре.

2 голосов
/ 02 ноября 2017

Я написал метод C #, который 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();
    }
...