Кодування URL-адрес за допомогою C #


340

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

Після входу користувача я створюю змінну, яка створює шлях на їх локальній машині.

c: \ tempfolder \ date \ username

Проблема полягає в тому, що деякі імена користувачів викидають виняток "Незаконні символи". Наприклад, якщо моє ім’я користувача, mas|fenixце викине виняток ..

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

Я не хочу видаляти його з рядка, але папка з їх ім'ям користувача створюється через FTP на сервері. І це призводить до мого другого питання. Якщо я створюю папку на сервері, чи можу я залишити "незаконні символи"? Я запитую це лише тому, що сервер заснований на Linux, і я не впевнений, приймає це Linux чи ні.

EDIT: Здається, що кодування URL-адреси НЕ, що я хочу .. Ось що я хочу зробити:

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

Де% xx - значення ASCII або будь-яке інше значення, яке легко визначить символ.


Включіть це, щоб зробити файлові системи безпечними іменами папок: http://stackoverflow.com/questions/333175/is-there-a-way-of-making-strings-file-path-safe-in-c
missaghi

Відповіді:


191

Редагувати: Зауважте, що ця відповідь застаріла. Подивитися Сергія Кучука нижче для кращого виправлення

UrlEncoding зробить те, що ви тут пропонуєте. З C # ви просто використовуєте HttpUtility, як було сказано.

Ви також можете переробити незаконні символи, а потім замінити, але це стає набагато складнішим, оскільки вам доведеться мати якусь форму станкової машини (комутатор ... випадок, наприклад), щоб замінити правильними символами. З тих пірUrlEncode це робиться попереду, це досить легко.

Що стосується Linux проти Windows, то в Linux є деякі символи, які є прийнятними, але не в Windows, але я б не турбувався про це, оскільки ім'я папки можна повернути, розшифрувавши рядок Url, використовуючи UrlDecode, так що ви можете обійти зміни.


5
ця відповідь застаріла. прочитайте кілька відповідей нижче - станом на .net45 це може бути правильним рішенням: msdn.microsoft.com/en-us/library/…
blueberryfields

1
Для FTP кожна частина Uri (папка або ім'я файлу) може бути сконструйована за допомогою Uri.EscapeDataString (fileOrFolderName), що дозволяє використовувати всі символи, не сумісні з Uri (пробіли, unicode ...). Наприклад, щоб дозволити будь-який символ у імені файлу, використовуйте: req = (FtpWebRequest) WebRequest.Create (новий Uri (шлях + "/" + Uri.EscapeDataString (ім'я файлу))); Використовуючи HttpUtility.UrlEncode () замініть пробіли знаками плюс (+). Правильна поведінка для пошукових систем, але неправильна для імен файлів / папок.
Рено Бансель

asp.net блокує більшість xss в URL-адресі, оскільки ви отримуєте попередження коли ви намагаєтеся додати js-скрипт A potentially dangerous Request.Path value was detected from the client.
Навчання

510

Я експериментував з різними методами .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 дещо інше).

Редагувати:

Я додав другу таблицю з кодуванням для .NET 4.5. Дивіться цю відповідь: https://stackoverflow.com/a/21771206/216440

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

2
Це фантастична відповідь. Виявляється, я хотів використовувати Uri.EscapeDataString, а не включати System.Web. Дякуємо за цю таблицю
Серавий

7
Зауважте, що це вже не на 100% точно. Деякі функції дещо змінилися між .NET 4 та .NET 4.5. Дивіться stackoverflow.com/q/20003106/1068266 .
Леві Ботелхо

2
@Levi: Дякую за голову. Я додав другу відповідь до таблиці для .NET 4.5. Я відредагував оригінальну відповідь для посилання на другу таблицю.
Саймон Тевсі

Зауважте, що в документації .NET написано Не використовувати; призначений лише для сумісності браузера. Використовуйте UrlEncode. , але цей метод кодує безліч інших небажаних символів. Найближчий з них - Uri.EscapeUriStringале будьте обережні, він не підтримує nullаргумент.
Андрій

1
Я забув згадати, мій коментар вище для UrlPathEncode. Так в основному замініть UrlPathEncodeна Uri.EscapeUriString.
Андрій

278

Ви повинні кодувати лише ім’я користувача або іншу частину 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");

Сподіваємось, це допомагає. Також, як згадувалося в теедеї , вам все одно потрібно буде переконатися, що незаконні символи імен файлів видалені, інакше файлова система не сподобається шляху.


33
Використання методу HttpUtility.UrlPathEncode повинно запобігти проблемі, яку ви тут описуєте.
vipirtti

12
@DJ Pirtu: Це правда, що UrlPathEncode не вноситиме цих небажаних змін на шляху, проте він також не буде кодувати нічого після ?(оскільки передбачає, що рядок запиту вже закодований). У прикладі Дена Герберта схоже, що він робить вигляд Example, що текст вимагає кодування, тому HttpUtility.UrlPathEncode("http://www.google.com/search?q=Example");не вийде. Спробуйте це ?q=Ex&ple(де бажаний результат ?q=Ex%26ple). Він не працюватиме, оскільки (1) UrlPathEncode нічого не торкається після ?, і (2) UrlPathEncode не кодує &все одно.
Тім Гудмен

1
Дивіться тут: connect.microsoft.com/VisualStudio/feedback/details/551839/… Я мушу додати, що, звичайно, добре, що UrlPathEncode не кодує &, оскільки вам це потрібно для розмежування параметрів рядка запиту. Але бувають випадки, коли ви хочете і закодовані амперсанди.
Тім Гудман

10
В останніх версіях HttpUtility наслідує WebUtility, економте собі час :)
Wiseman

190

Кращим способом є використання

Uri.EscapeUriString

до посилання Повний профіль .net 4.


1
Цілком погоджуюся, оскільки часто "Профіль клієнта" достатньо для програм, що використовують System.Net, але не використовують System.Web ;-)
hfrmobile

6
OP говорить про те, щоб перевірити його на сумісність файлової системи, тому це не спрацює. Набір заборонених наборів символів Windows - '["/", "\\", "<", ">", ":", "\" "," | ","? "," * "]', Але багато з них не кодуйтесь за допомогою EscapedUriString (див. таблицю нижче - спасибі за цю таблицю @Simon Tewsi) ... "створює шлях на їх локальній машині" -OP UrlEncoded піклується про майже всі проблеми, але не вирішує проблема з тим, що "%" або "% 3f" знаходяться в оригінальному введенні, оскільки "декодування" тепер буде іншим, ніж оригінал.
m1m1k

6
просто для того, щоб було зрозуміло: ЦЕ відповідь ЧИСТА РОБОТА для файлових систем
m1m1k

1
Крім того, починаючи з .NET Framework 4.5, профіль клієнта було припинено і доступний лише повний перерозподільний пакет.
twomm

29
stackoverflow.com/a/34189188/3436164 Використовуйте Uri.EscapeDataStringНЕ Uri.EscapeUriStringПрочитайте цей коментар, це допомогло мені.
ykadaru

181

Оскільки ви повинні використовувати .NET Framework 4.5 та .NET Standard 1.0WebUtility.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.


Мені подобається, як він кодує використання "+" замість% 20 ​​для пробілів .. але цей все ще не видаляє "з URL-адреси та дає мені недійсну URL-адресу ... ой добре .. просто доведеться зробити заміну (" "" "," ")
Пьотр Кула

84

Леві Ботелхо прокоментував, що раніше створена таблиця кодувань більше не є точною для .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. В результаті відповіді на розбрат я додав нові методи UrlEncode і HtmlEncode WebUtility, які були введені в .NET 4.5.

2
Ніхто не користувач UrlPathEncode - навіть MSDN говорить, що його не слід використовувати. Він був створений, щоб виправити проблему з netscape
Jeff

Чи є сервер.URLEncode ще однією варіантом цієї теми? Чи генерує це якийсь інший вихід?
ALEXintlsos

2
@ALEX: В ASP.NET об’єкт Server - це екземпляр HttpServerUtility. За допомогою декомпілятора dotPeek я подивився на HttpServerUtility.UrlEncode. Він просто викликає HttpUtility.UrlEncode, щоб результат двох методів був однаковим.
Саймон Тевсі

Схоже, навіть при такій надмірності методів кодування, вони все ще досить ефектно спрацьовують у порівнянні з Latin-1, наприклад → або ☠. (Схоже, UrlEncodedUnicode ніби намагається підтримати Unicode, але застарілий / відсутній.)
brianary

Саймоне, ти можеш просто включити цю відповідь у прийняту відповідь? буде приємно мати це в одній відповіді. ви можете інтегрувати його та зробити заголовок h1 внизу цієї відповіді або інтегруватись в одну таблицю та позначати різні рядки, як-от: (Net4.0) ? %3f................................ (Net4.5) ? %3f ..................................
T.Todua

60

Кодування URL легко в .NET. Використання:

System.Web.HttpUtility.UrlEncode(string url)

Якщо це буде розшифровано, щоб отримати ім’я папки, вам все одно потрібно буде виключити символи, які не можна використовувати у назвах папок (*,?, / Тощо)


Чи кодує він кожного символу, який не входить до алфавіту?
masfenix

1
Кодування URL перетворює символи, які не дозволені в URL-адресі, в еквіваленти символьних об'єктів. Список небезпечних персонажів: blooberry.com/indexdot/html/topics/urlencoding.htm
Іван Робінсон

Посилання MSDN на HttpUtility.UrlEncode: msdn.microsoft.com/en-us/library/4fkewx0t.aspx
Іван Робінсон

11
Добре застосовувати повний System.Web ... участь у вашій відповіді, це економить багато людей мало часу :) дякую
Ліам

3
Це небезпечно: не всі символи URL-адреси повинні бути закодовані, лише значення параметрів запиту рядків. Запропонований вами спосіб кодує також &, що потрібно для створення декількох параметрів у рядку запитів. Суть полягає в кодуванні кожного значення параметрів, якщо це потрібно
Marco Staffoli

12

Якщо ви не бачите System.Web, змініть налаштування свого проекту. Цільовим каркасом має бути ".NET Framework 4" замість ".NET Framework 4 Profile Client"


1
На мою думку, розробники повинні знати про ".NET Profiles", і вони повинні використовувати правильний для своїх цілей! Просто додавання повного профілю для отримання (наприклад, System.Web), не знаючи, чому вони додають повний профіль, не дуже розумно. Використовуйте "Профіль клієнта" для своїх клієнтських додатків та повного профілю лише у разі потреби (наприклад, клієнт WinForms або WPF повинен використовувати профіль клієнта, а не повний профіль)! Наприклад, я не бачу причини використовувати HttpServerUtility у клієнтському додатку ^^ ... якщо це потрібно, то в дизайні додатка щось не так!
hfrmobile

4
Дійсно? Ви ніколи не бачите потреби в клієнтському додатку для створення URL-адреси? Чим ти займаєшся на життя - двірники?
sproketboy

@hfrmobile: ні. Це все неправильно з профільною моделлю (яка жила лише один раз і була покинута в наступній версії). І це було очевидно з самого початку. Це для вас зараз очевидно? Подумайте спочатку, не сприймайте все "як є", що msft намагається вам продати; P
абатищев,

Вибачте, але я ніколи не говорив, що клієнт ніколи не повинен створювати / використовувати URL-адресу. Поки .NET 4.0 використовується, користувач повинен дбати про це. Якщо коротко, розробники повинні подумати двічі, перш ніж додати HttpServerUtility клієнту. Є й інші / кращі способи, просто подивіться відповідь зі 139 голосами або "Оскільки .NET Framework 4.5 ви можете використовувати WebUtility.UrlEncode. По-перше, він знаходиться в System.dll, тому не потребує додаткових посилань."
hfrmobile

9

Реалізація .NET UrlEncodeне відповідає RFC 3986.

  1. Деякі символи не закодовані, але повинні бути. Ці !()*символи перераховані в розділі RFC, 2.2 в якості зарезервованих символів , які повинні бути закодовані ще .NET не може закодувати ці символи.

  2. Деякі символи закодовані, але не повинні бути. Ці .-_символи не перераховано в розділі RFC, 2.2 як зарезервований символ , який не повинен бути закодований ще .NET помилково кодує ці символи.

  3. RFC вказує, що, щоб бути послідовними, реалізації повинні використовувати великі регістри HEXDIG, де .NET виробляє нижній регістр HEXDIG.


4

Я думаю, що тут людей відхилили повідомлення UrlEncode. URLEncoding - це не те, що потрібно. Ви хочете кодувати речі, які не працюватимуть як ім'я файлу в цільовій системі.

Якщо припустити, що ви хочете певної загальності - сміливо знаходьте незаконні символи в декількох системах (MacOS, Windows, Linux і Unix), об'єднайте їх, щоб сформувати набір символів для виходу.

Щодо втечі, HexEscape повинен бути добре (Заміна символів на% XX). Перетворіть кожен символ у байти UTF-8 і закодуйте все> 128, якщо ви хочете підтримувати системи, які не роблять unicode. Але є й інші способи, такі як використання косої косої риски "\" або кодування HTML "" ". Ви можете створити свій власний. Все, що потрібно зробити, це" кодувати "геть несумісний символ. Наведені вище системи дозволяють відтворити оригінальна назва - але працює щось на зразок заміни поганих символів пробілами.

На тій самій дотичній, що і вище, використовується єдиний

Uri.EscapeDataString

- Він кодує все, що потрібно для OAuth, він не кодує речі, які OAuth забороняє кодувати, і кодує простір як% 20, а не + (також у специфікації OATH) Див. RFC 3986. AFAIK, це остання специфікація URI


3

Я написав метод 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();
    }

1

В ідеалі вони входять у клас під назвою "FileNaming" або, можливо, просто перейменовують кодування у "FileNameEncode". Примітка: вони не розроблені для обробки повних контурів, а лише імена папок та / або файлів. В ідеалі ви спочатку розділите ("/") ваш повний шлях, а потім перевірите шматки. І очевидно, замість об'єднання, ви можете просто додати символ "%" до списку символів, не дозволених у Windows, але я вважаю, що це більш корисно / читабельно / фактично. Декодування () точно таке ж, але перемикання символу заміни (Uri.HexEscape (s [0]), s) "втекло".

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

Дякуємо @ simon-tewsi за дуже корисну таблицю вище!


також корисно: Path.GetInvalidFileNameChars()
m1m1k

так. Ось один із способів цього: foreach (char c у System.IO.Path.GetInvalidFileNameChars ()) {filename = filename.Replace (c, '_'); }
netfed

0

На додаток до відповіді @Dan Herbert, Ви повинні загалом кодувати лише значення.

Split має параметри параметри Split ('&', '='); вираз спочатку розділений на & then '=', тому непарні елементи - це всі значення, які потрібно закодувати, показані нижче.

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);
        }
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.