Pengkodean URL menggunakan C #


340

Saya memiliki aplikasi yang mengirimkan permintaan POST ke perangkat lunak forum VB dan mencatat seseorang (tanpa mengatur cookie atau apa pun).

Setelah pengguna masuk saya membuat variabel yang membuat jalur di mesin lokal mereka.

c: \ tempfolder \ date \ username

Masalahnya adalah beberapa nama pengguna melempar pengecualian "karakter ilegal". Misalnya jika nama pengguna saya mas|fenixitu akan membuang pengecualian ..

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

Saya tidak ingin menghapusnya dari string, tetapi folder dengan nama pengguna mereka dibuat melalui FTP di server. Dan ini mengarah ke pertanyaan kedua saya. Jika saya membuat folder di server, bisakah saya meninggalkan "karakter ilegal"? Saya hanya menanyakan ini karena servernya berbasis Linux, dan saya tidak yakin apakah Linux menerimanya atau tidak.

EDIT: Tampaknya penyandian URL BUKAN yang saya inginkan .. Inilah yang ingin saya lakukan:

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

Di mana% xx adalah nilai ASCII atau nilai lainnya yang akan dengan mudah mengidentifikasi karakter.


Jawaban:


191

Sunting: Perhatikan bahwa jawaban ini sekarang kedaluwarsa. Lihat jawaban Siarhei Kuchuk di bawah ini untuk perbaikan yang lebih baik

UrlEncoding akan melakukan apa yang Anda sarankan di sini. Dengan C #, Anda cukup menggunakan HttpUtility, seperti yang disebutkan.

Anda juga dapat Regex karakter ilegal dan kemudian ganti, tetapi ini menjadi jauh lebih kompleks, karena Anda harus memiliki beberapa bentuk mesin negara (beralih ... kasus, misalnya) untuk mengganti dengan karakter yang benar. Karena UrlEncodemelakukan ini di depan, itu agak mudah.

Adapun Linux versus windows, ada beberapa karakter yang dapat diterima di Linux yang tidak ada di Windows, tapi saya tidak akan khawatir tentang itu, karena nama folder dapat dikembalikan dengan mendekode string Url, menggunakan UrlDecode, sehingga Anda dapat round trip perubahan.


5
jawaban ini sudah usang sekarang. baca beberapa jawaban di bawah - pada .net45 ini mungkin solusi yang tepat: msdn.microsoft.com/en-us/library/…
blueberryfields

1
Untuk FTP, setiap bagian Uri (folder atau nama file) dapat dibangun menggunakan Uri.EscapeDataString (fileOrFolderName) yang memungkinkan semua karakter yang tidak kompatibel dengan Uri (spasi, unicode ...). Misalnya untuk mengizinkan karakter apa pun dalam namafile, gunakan: req = (FtpWebRequest) WebRequest.Create (Uri baru (jalur + "/" + Uri.EscapeDataString (nama file))); Menggunakan HttpUtility.UrlEncode () ganti spasi dengan tanda plus (+). Perilaku yang benar untuk mesin pencari tetapi salah untuk nama file / folder.
Renaud Bancel

asp.net memblokir sebagian besar xss di url saat Anda mendapat peringatan ketika Anda mencoba menambahkan skrip js A potentially dangerous Request.Path value was detected from the client.
Belajar

511

Saya telah bereksperimen dengan berbagai metode .NET menyediakan untuk pengkodean URL. Mungkin tabel berikut ini akan berguna (sebagai keluaran dari aplikasi uji yang saya tulis):

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]

Kolom mewakili penyandian sebagai berikut:

  • UrlEkode: HttpUtility.UrlEncode

  • UrlEncodedUnicode: HttpUtility.UrlEncodeUnicode

  • UrlPathEncoded: HttpUtility.UrlPathEncode

  • EscapedDataString: Uri.EscapeDataString

  • EscapedUriString: Uri.EscapeUriString

  • HtmlEkode: HttpUtility.HtmlEncode

  • HtmlAttributeEncoded: HttpUtility.HtmlAttributeEncode

  • HexEscaped: Uri.HexEscape

CATATAN:

  1. HexEscapehanya dapat menangani 255 karakter pertama. Oleh karena itu ia mengeluarkan ArgumentOutOfRangepengecualian untuk karakter A-Extended Latin (misalnya Ā).

  2. Tabel ini dibuat di .NET 4.0 (lihat komentar Levi Botelho di bawah ini yang mengatakan penyandian dalam .NET 4.5 sedikit berbeda).

EDIT:

Saya telah menambahkan tabel kedua dengan penyandian untuk .NET 4.5. Lihat jawaban ini: https://stackoverflow.com/a/21771206/216440

EDIT 2:

Karena orang-orang tampaknya menghargai tabel ini, saya pikir Anda mungkin menyukai kode sumber yang menghasilkan tabel, sehingga Anda dapat bermain-main sendiri. Ini adalah aplikasi konsol C # sederhana, yang dapat menargetkan .NET 4.0 atau 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
Ini jawaban yang fantastis. Ternyata saya ingin menggunakan Uri.EscapeDataString dan tidak termasuk System.Web. Terima kasih untuk tabel ini.
Seravy

7
Perhatikan bahwa ini tidak lagi 100% akurat. Beberapa fungsi telah sedikit berubah antara .NET 4 dan .NET 4.5. Lihat stackoverflow.com/q/20003106/1068266 .
Levi Botelho

2
@Levi: Terima kasih atas kepalanya. Saya telah menambahkan jawaban kedua dengan tabel untuk .NET 4.5. Saya telah mengedit jawaban asli untuk menautkan ke tabel kedua.
Simon Tewsi

Perhatikan bahwa dokumentasi .NET mengatakan Jangan gunakan; dimaksudkan hanya untuk kompatibilitas browser. Gunakan UrlEncode. , tetapi metode itu mengkodekan banyak karakter yang tidak diinginkan lainnya. Yang terdekat adalah Uri.EscapeUriString, tetapi waspadalah itu tidak mendukung nullargumen.
Andrew

1
Saya lupa menyebutkan, komentar saya di atas adalah untuk UrlPathEncode. Jadi pada dasarnya gantikan UrlPathEncodedengan Uri.EscapeUriString.
Andrew

279

Anda harus menyandikan hanya nama pengguna atau bagian lain dari URL yang bisa tidak valid. Pengkodean URL dapat menyebabkan masalah karena sesuatu seperti ini:

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

Akan menghasilkan

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

Ini jelas tidak akan bekerja dengan baik. Sebagai gantinya, Anda harus menyandikan HANYA nilai pasangan kunci / nilai dalam string kueri, seperti ini:

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

Semoga itu bisa membantu. Juga, seperti yang disebutkan teedyay , Anda masih perlu memastikan karakter nama file ilegal dihapus atau sistem file tidak akan suka jalannya.


34
Menggunakan metode HttpUtility.UrlPathEncode harus mencegah masalah yang Anda uraikan di sini.
vipirtti

12
@DJ Pirtu: Memang benar bahwa UrlPathEncode tidak akan membuat perubahan yang tidak diinginkan di jalur, namun juga tidak akan menyandikan apa pun setelah ?(karena mengasumsikan string kueri sudah dikodekan). Dalam contoh Dan Herbert sepertinya dia berpura-pura Exampleadalah teks yang membutuhkan penyandian, jadi HttpUtility.UrlPathEncode("http://www.google.com/search?q=Example");tidak akan berfungsi. Cobalah dengan ?q=Ex&ple(di mana hasil yang diinginkan ?q=Ex%26ple). Ini tidak akan berfungsi karena (1) UrlPathEncode tidak menyentuh apa pun setelahnya ?, dan (2) UrlPathEncode tetap tidak menyandikan &.
Tim Goodman

1
Lihat di sini: connect.microsoft.com/VisualStudio/feedback/details/551839/... Saya harus menambahkan itu tentu saja baik UrlPathEncode tidak menyandikan &, karena Anda perlu membatasi parameter string kueri Anda. Tapi ada kalanya Anda ingin ampersand yang disandikan juga.
Tim Goodman

10
HttpUtility digantikan oleh WebUtility dalam versi terbaru, hemat waktu Anda :)
Wiseman

190

Cara yang lebih baik adalah menggunakan

Uri.EscapeUriString

untuk tidak merujuk Profil Lengkap .net 4.


1
Sepenuhnya setuju karena seringkali "Profil Klien" sudah cukup untuk aplikasi menggunakan System.Net tetapi tidak menggunakan System.Web ;-)
hfrmobile

6
OP berbicara tentang memeriksa kompatibilitas sistem file, jadi ini tidak akan berfungsi. Rangkaian karakter yang dilarang Windows adalah '["/", "\\", "<", ">", ":", "\" "," | ","? "," * "]' Tetapi banyak di antaranya jangan disandikan menggunakan EscapedUriString (lihat tabel di bawah ini - terima kasih untuk tabel itu @Simon Tewsi) ... "membuat jalur pada mesin lokal mereka" -OP UrlEncoded menangani hampir semua masalah, tetapi tidak menyelesaikan masalah dengan "%" atau "% 3f" berada di input asli, sebagai "decode" sekarang akan berbeda dari yang asli
m1m1k

6
hanya untuk memperjelas: jawaban INI TIDAK BEKERJA untuk sistem file
m1m1k

1
Selain itu, dimulai dengan .NET Framework 4.5, Profil Klien telah dihentikan dan hanya paket lengkap yang dapat didistribusikan kembali yang tersedia.
twomm

29
stackoverflow.com/a/34189188/3436164 Gunakan Uri.EscapeDataStringTIDAK Uri.EscapeUriStringBaca komentar ini, itu membantu saya keluar.
ykadaru

181

Karena .NET Framework 4.5 dan .NET Standard 1.0 harus Anda gunakan WebUtility.UrlEncode. Keuntungan dibandingkan alternatif:

  1. Ini adalah bagian dari .NET Framework 4.5+, .NET Core 1.0+, .NET Standard 1.0+, UWP 10.0+ dan semua platform Xamarin juga. HttpUtility, sementara tersedia di .NET Framework sebelumnya (.NET Framework 1.1+), menjadi tersedia di platform lain jauh lebih baru (.NET Core 2.0+, .NET Standard 2.0+) dan masih belum tersedia di UWP (lihat pertanyaan terkait ).

  2. Dalam .NET Framework, ia berada diSystem.dll , sehingga tidak memerlukan referensi tambahan, tidak seperti HttpUtility.

  3. Itu benar lolos karakter untuk URL , tidak seperti Uri.EscapeUriString(lihat komentar untuk jawaban drweb86 ).

  4. Itu tidak memiliki batas pada panjang string , tidak seperti Uri.EscapeDataString(lihat pertanyaan terkait ), sehingga dapat digunakan untuk permintaan POST, misalnya.


Saya suka cara encode menggunakan "+" alih-alih% 20 untuk spasi .. tapi yang ini masih tidak menghapus "dari URL dan memberi saya URL tidak valid ... oh well .. hanya harus melakukan aa ganti (" "" "", "")
Piotr Kula

85

Levi Botelho berkomentar bahwa tabel penyandian yang sebelumnya dibuat tidak lagi akurat untuk .NET 4.5, karena penyandian sedikit berubah antara .NET 4.0 dan 4.5. Jadi saya telah membuat ulang tabel untuk .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]

Kolom mewakili penyandian sebagai berikut:

  • UrlEkode: HttpUtility.UrlEncode
  • UrlEncodedUnicode: HttpUtility.UrlEncodeUnicode
  • UrlPathEncoded: HttpUtility.UrlPathEncode
  • WebUtilitasUrlDitode: WebUtility.UrlEncode
  • EscapedDataString: Uri.EscapeDataString
  • EscapedUriString: Uri.EscapeUriString
  • HtmlEkode: HttpUtility.HtmlEncode
  • HtmlAttributeEncoded: HttpUtility.HtmlAttributeEncode
  • WebUtilitasHtmlEkode: WebUtility.HtmlEncode
  • HexEscaped: Uri.HexEscape

CATATAN:

  1. HexEscape hanya dapat menangani 255 karakter pertama. Oleh karena itu ia melempar pengecualian ArgumentOutOfRange untuk karakter A-Extended Latin (misalnya Ā).

  2. Tabel ini dibuat di .NET 4.5 (lihat jawaban https://stackoverflow.com/a/11236038/216440 untuk penyandian yang relevan dengan .NET 4.0 dan di bawah).

EDIT:

  1. Sebagai hasil dari jawaban Discord saya menambahkan metode WebUtility UrlEncode dan HtmlEncode baru, yang diperkenalkan dalam .NET 4.5.

2
Tidak ada pengguna UrlPathEncode - bahkan MSDN mengatakan itu tidak boleh digunakan. Itu dibangun untuk memperbaiki masalah dengan netscape 2 msdn.microsoft.com/en-us/library/…
Jeff

Apakah Server.URLEncode merupakan variasi lain dari tema ini? Apakah ini menghasilkan output yang berbeda?
ALEXintlsos

2
@ALEX: Dalam ASP.NET objek Server adalah turunan dari HttpServerUtility. Menggunakan decompiler dotPeek saya telah melihat HttpServerUtility.UrlEncode. Itu hanya memanggil HttpUtility.UrlEncode sehingga output dari kedua metode akan sama.
Simon Tewsi

Sepertinya, bahkan dengan meluap-luapnya metode pengkodean ini, mereka semua masih gagal cukup spektakuler untuk apa pun di atas Latin-1, seperti → atau ☠. (UrlEncodedUnicode tampaknya seperti itu setidaknya mencoba untuk mendukung Unicode, tetapi sudah usang / hilang.)
brianary

Simon, bisakah kamu mengintegrasikan jawaban ini ke dalam jawaban yang diterima? akan menyenangkan untuk memilikinya dalam satu jawaban. Anda dapat mengintegrasikannya dan membuat judul h1 di bagian bawah jawaban itu, atau mengintegrasikannya dalam satu tabel, dan menandai baris yang berbeda, seperti: (Net4.0) ? %3f................................ (Net4.5) ? %3f ..................................
T.Todua

60

Pengkodean URL mudah di .NET. Menggunakan:

System.Web.HttpUtility.UrlEncode(string url)

Jika itu akan diterjemahkan untuk mendapatkan nama folder, Anda masih perlu mengecualikan karakter yang tidak dapat digunakan dalam nama folder (*,?, /, Dll.)


Apakah ini menyandikan setiap karakter yang bukan bagian dari alfabet?
masfenix

1
Pengkodean URL mengubah karakter yang tidak diizinkan dalam URL ke dalam persamaan karakter-entitas. Daftar karakter yang tidak aman: blooberry.com/indexdot/html/topics/urlencoding.htm
Ian Robinson

Tautan MSDN di HttpUtility.UrlEncode: msdn.microsoft.com/en-us/library/4fkewx0t.aspx
Ian Robinson

11
Ini adalah praktik yang baik untuk menempatkan System.Web penuh ... bagian dalam jawaban Anda, itu menghemat banyak orang sedikit waktu :) terima kasih
Liam

3
Ini berbahaya: tidak semua karakter url harus dikodekan, hanya nilai-nilai parameter querystring. Cara Anda menyarankan akan menyandikan & yang diperlukan untuk membuat beberapa parameter dalam querystring. Soution adalah untuk menyandikan setiap nilai parameter jika diperlukan
Marco Staffoli

12

Jika Anda tidak dapat melihat System.Web, ubah pengaturan proyek Anda. Kerangka target harus ".NET Framework 4" alih-alih ".NET Framework 4 Profil Klien"


1
Menurut pendapat saya pengembang harus tahu tentang ".NET Profil" dan mereka harus menggunakan yang benar untuk keperluan mereka! Hanya menambahkan profil lengkap untuk mendapatkan (misalnya System.Web) tanpa benar-benar tahu mengapa mereka menambahkan profil lengkap, tidak terlalu pintar. Gunakan "Profil Klien" untuk aplikasi klien Anda dan profil lengkap hanya jika diperlukan (mis. Klien WinForms atau WPF harus menggunakan profil klien dan bukan profil lengkap)! misalnya saya tidak melihat alasan menggunakan HttpServerUtility di aplikasi klien ^^ ... jika ini diperlukan maka ada sesuatu yang salah dengan desain aplikasi!
hfrmobile

4
Betulkah? Jangan pernah melihat kebutuhan aplikasi klien untuk membuat URL? Apa yang Anda lakukan untuk hidup - tugas kebersihan?
sproketboy

@ hfrmobile: tidak. Semuanya salah dengan model profil (yang hanya hidup sekali dan ditinggalkan di versi berikutnya). Dan itu sudah jelas sejak awal. Apakah sudah jelas bagi Anda sekarang? Pikirkan dulu, jangan terima semuanya 'apa adanya' apa yang coba dijual msft kepadamu; P
abatishchev

Maaf, tetapi saya tidak pernah mengatakan bahwa klien tidak perlu membuat / menggunakan URL. Selama. NET 4.0 digunakan, pengguna harus peduli. Singkatnya: Pengembang harus berpikir dua kali sebelum menambahkan HttpServerUtility ke klien. Ada cara lain / lebih baik, lihat saja jawabannya dengan 139 suara atau "Sejak .NET Framework 4.5 Anda dapat menggunakan WebUtility.UrlEncode. Pertama, ia berada di System.dll, sehingga tidak memerlukan referensi tambahan.".
hfrmobile

9

Implementasi .NET UrlEncodetidak sesuai dengan RFC 3986.

  1. Beberapa karakter tidak dikodekan tetapi harus. Para !()*karakter tercantum dalam RFC ini bagian 2.2 sebagai karakter pendiam yang harus dikodekan belum NET gagal untuk mengkodekan karakter ini.

  2. Beberapa karakter dikodekan tetapi tidak boleh. Para .-_karakter tidak terdaftar di bagian RFC 2.2 sebagai karakter pendiam yang tidak dikodekan belum NET keliru mengkodekan karakter ini.

  3. RFC menetapkan bahwa agar konsisten, implementasi harus menggunakan huruf besar HEXDIG, di mana .NET menghasilkan huruf kecil HEXDIG.


4

Saya pikir orang-orang di sini teralihkan oleh pesan UrlEncode. URLEncoding bukan yang Anda inginkan - Anda ingin menyandikan hal-hal yang tidak akan berfungsi sebagai nama file pada sistem target.

Dengan asumsi bahwa Anda ingin generalisasi - jangan ragu untuk menemukan karakter ilegal di beberapa sistem (MacOS, Windows, Linux dan Unix), gabungkan mereka untuk membentuk serangkaian karakter untuk melarikan diri.

Sedangkan untuk pelarian, HexEscape harus baik-baik saja (Mengganti karakter dengan% XX). Ubah setiap karakter menjadi UTF-8 byte dan enkode semuanya> 128 jika Anda ingin mendukung sistem yang tidak melakukan unicode. Tetapi ada cara lain, seperti menggunakan back slash "\" atau HTML encoding "" ". Anda dapat membuatnya sendiri. Yang harus dilakukan oleh sistem adalah 'menyandikan' karakter yang tidak kompatibel tersebut. Sistem di atas memungkinkan Anda untuk membuat ulang nama asli - tetapi sesuatu seperti mengganti karakter buruk dengan spasi juga berfungsi.

Pada garis singgung yang sama seperti di atas, satu-satunya yang digunakan adalah

Uri.EscapeDataString

- Ini mengkodekan semua yang diperlukan untuk OAuth, itu tidak mengkodekan hal-hal yang OAuth melarang pengkodean, dan menyandikan ruang sebagai% 20 dan bukan + (Juga dalam Spesifikasi OATH) Lihat: RFC 3986. AFAIK, ini adalah spesifikasi URI terbaru.


3

Saya telah menulis metode C # yang url-encode SEMUA simbol:

    /// <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

Idealnya ini akan masuk dalam kelas yang disebut "FileNaming" atau mungkin hanya mengubah nama Encode menjadi "FileNameEncode". Catatan: ini tidak dirancang untuk menangani Jalur Lengkap, hanya folder dan / atau nama file. Idealnya Anda akan Membagi ("/") path lengkap Anda terlebih dahulu dan kemudian memeriksa bagian. Dan jelas, alih-alih gabungan, Anda bisa menambahkan karakter "%" ke daftar karakter yang tidak diizinkan di Windows, tapi saya pikir ini lebih membantu / dapat dibaca / faktual dengan cara ini. Decode () persis sama tetapi mengganti Replace (Uri.HexEscape (s [0]), s) "lolos" dengan karakter.

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

Terima kasih @ simon-tewsi untuk tabel yang sangat berguna di atas!


juga bermanfaat: Path.GetInvalidFileNameChars()
m1m1k

Iya. Inilah salah satu cara melakukannya: foreach (char c di System.IO.Path.GetInvalidFileNameChars ()) {filename = filename.Replace (c, '_'); }
netfed

0

Selain jawaban @Dan Herbert, Anda harus menyandikan nilai secara umum saja.

Split memiliki parameter parameter Split ('&', '='); ekspresi pertama-tama dipisah oleh & kemudian '=' sehingga elemen ganjil adalah semua nilai yang akan dikodekan ditunjukkan di bawah.

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);
        }
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.