Mã hóa URL bằng C #


340

Tôi có một ứng dụng gửi yêu cầu POST đến phần mềm diễn đàn VB và đăng nhập một ai đó (không cần đặt cookie hay bất cứ thứ gì).

Khi người dùng đã đăng nhập, tôi tạo một biến tạo đường dẫn trên máy cục bộ của họ.

c: \ tempfolder \ date \ tên người dùng

Vấn đề là một số tên người dùng đang ném ngoại lệ "ký tự bất hợp pháp". Ví dụ: nếu tên người dùng của tôi là mas|fenixnó sẽ ném một ngoại lệ ..

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

Tôi không muốn xóa nó khỏi chuỗi, nhưng một thư mục có tên người dùng của họ được tạo thông qua FTP trên máy chủ. Và điều này dẫn đến câu hỏi thứ hai của tôi. Nếu tôi đang tạo một thư mục trên máy chủ, tôi có thể để lại "ký tự bất hợp pháp" không? Tôi chỉ hỏi điều này vì máy chủ dựa trên Linux và tôi không chắc liệu Linux có chấp nhận hay không.

EDIT: Có vẻ như mã hóa URL KHÔNG phải là điều tôi muốn .. Đây là những gì tôi muốn làm:

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

Trong đó% xx là giá trị ASCII hoặc bất kỳ giá trị nào khác có thể dễ dàng xác định ký tự.


Kết hợp điều này để tạo tên thư mục an toàn cho hệ thống tệp: http://stackoverflow.com/questions/333175/is-there-a-way-of-making-strings-file-path-safe-in-c
missaghi

Câu trả lời:


191

Chỉnh sửa: Lưu ý rằng câu trả lời này đã hết hạn. Xem câu trả lời của Siarhei Kuchuk dưới đây để có cách khắc phục tốt hơn

UrlEncoding sẽ làm những gì bạn đang đề xuất ở đây. Với C #, bạn chỉ cần sử dụng HttpUtility, như đã đề cập.

Bạn cũng có thể Regex các ký tự không hợp lệ và sau đó thay thế, nhưng điều này phức tạp hơn nhiều, vì bạn sẽ phải có một số dạng máy trạng thái (ví dụ ... trường hợp ... chẳng hạn) để thay thế bằng các ký tự chính xác. Vì UrlEncodeđiều này lên phía trước, nó khá dễ dàng.

Đối với Linux so với windows, có một số ký tự được chấp nhận trong Linux không có trong Windows, nhưng tôi không lo lắng về điều đó, vì tên thư mục có thể được trả về bằng cách giải mã chuỗi Url UrlDecode, vì vậy bạn có thể làm tròn chuyến đi thay đổi.


5
Câu trả lời này đã hết hạn. đọc một vài câu trả lời dưới đây - kể từ .net45 đây có thể là giải pháp chính xác: msdn.microsoft.com/en-us/l
blueberryfields

1
Đối với FTP, mỗi phần Uri (tên thư mục hoặc tên tệp) có thể được xây dựng bằng Uri.EscapeDataString (fileOrFolderName) cho phép tất cả các ký tự không tương thích Uri (dấu cách, unicode ...). Ví dụ: để cho phép bất kỳ ký tự nào trong tên tệp, hãy sử dụng: req = (FtpWebRequest) WebRequest.Create (new Uri (path + "/" + Uri.EscapeDataString (tên tệp)); Sử dụng HttpUtility.UrlEncode () thay thế khoảng trắng bằng dấu cộng (+). Một hành vi đúng cho các công cụ tìm kiếm nhưng không chính xác cho tên tệp / thư mục.
Renaud Belon 17/2/2015

asp.net chặn phần lớn xss trong url khi bạn nhận được cảnh báo khi bạn cố gắng thêm tập lệnh js A potentially dangerous Request.Path value was detected from the client.
Học

510

Tôi đã thử nghiệm các phương pháp khác nhau mà .NET cung cấp cho mã hóa URL. Có lẽ bảng sau sẽ hữu ích (như đầu ra từ một ứng dụng thử nghiệm tôi đã viết):

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]

Các cột biểu thị mã hóa như sau:

  • Mã hóa: HttpUtility.UrlEncode

  • UrlEncodingUnicode: HttpUtility.UrlEncodeUnicode

  • UrlPathEncoding: HttpUtility.UrlPathEncode

  • Đã thoátDataString: Uri.EscapeDataString

  • EscgedUriString: Uri.EscapeUriString

  • HtmlEncoding: HttpUtility.HtmlEncode

  • HtmlAttributionEncoding: HttpUtility.HtmlAttributeEncode

  • HexEscoped: Uri.HexEscape

GHI CHÚ:

  1. HexEscapechỉ có thể xử lý 255 ký tự đầu tiên. Vì vậy, nó ném mộtArgumentOutOfRange ngoại lệ cho các ký tự A-Extended Latin (ví dụ).

  2. Bảng này được tạo trong .NET 4.0 (xem bình luận của Levi Botelho bên dưới cho biết mã hóa trong .NET 4.5 hơi khác một chút).

BIÊN TẬP:

Tôi đã thêm một bảng thứ hai với các bảng mã cho .NET 4.5. Xem câu trả lời này: https://stackoverflow.com/a/21771206/216440

EDIT 2:

Vì mọi người dường như đánh giá cao các bảng này, tôi nghĩ rằng bạn có thể thích mã nguồn tạo ra bảng, vì vậy bạn có thể tự chơi xung quanh mình. Đây là một ứng dụng bảng điều khiển C # đơn giản, có thể nhắm mục tiêu .NET 4.0 hoặc 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
Đây là một câu trả lời tuyệt vời. Hóa ra tôi muốn sử dụng Uri.EscapeDataString và không bao gồm System.Web. Cảm ơn cho bảng này.
Ser lượn

7
Lưu ý rằng điều này không còn chính xác 100%. Một số chức năng đã thay đổi một chút giữa .NET 4 và .NET 4.5. Xem stackoverflow.com/q/20003106/1068266 .
Levi Botelho

2
@Levi: Cảm ơn vì đã ngẩng cao đầu. Tôi đã thêm câu trả lời thứ hai với bảng cho .NET 4.5. Tôi đã chỉnh sửa câu trả lời ban đầu để liên kết đến bảng thứ hai.
Simon Tewsi

Lưu ý rằng tài liệu .NET nói Không sử dụng; chỉ dành cho khả năng tương thích trình duyệt. Sử dụng UrlEncode. , nhưng phương thức đó mã hóa rất nhiều ký tự không mong muốn khác. Cách gần nhất là Uri.EscapeUriString, nhưng hãy cẩn thận, nó không hỗ trợ một nullđối số.
Andrew

1
Tôi quên đề cập, bình luận của tôi ở trên là cho UrlPathEncode. Vì vậy, về cơ bản thay thế UrlPathEncodebằng Uri.EscapeUriString.
Andrew

278

Bạn chỉ nên mã hóa tên người dùng hoặc phần khác của URL có thể không hợp lệ. Mã hóa URL một URL có thể dẫn đến các vấn đề vì một cái gì đó như thế này:

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

Sẽ mang lại

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

Điều này rõ ràng là sẽ không hoạt động tốt. Thay vào đó, bạn nên mã hóa CHỈ giá trị của cặp khóa / giá trị trong chuỗi truy vấn, như sau:

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

Hy vọng rằng sẽ giúp. Ngoài ra, như teedyay đã đề cập, bạn vẫn cần đảm bảo xóa các ký tự tên tệp bất hợp pháp nếu không hệ thống tệp sẽ không giống như đường dẫn.


33
Sử dụng phương thức HttpUtility.UrlPathEncode sẽ ngăn chặn sự cố bạn mô tả ở đây.
vipirtti

12
@DJ Pirtu: Đúng là UrlPathEncode sẽ không thực hiện những thay đổi không mong muốn đó trong đường dẫn, tuy nhiên nó cũng sẽ không mã hóa bất cứ điều gì sau ?(vì nó giả sử chuỗi truy vấn đã được mã hóa). Trong ví dụ của Dan Herbert, có vẻ như anh ta giả vờ Examplelà văn bản yêu cầu mã hóa, vì vậy HttpUtility.UrlPathEncode("http://www.google.com/search?q=Example");sẽ không hoạt động. Hãy thử nó với ?q=Ex&ple(nơi kết quả mong muốn là ?q=Ex%26ple). Nó sẽ không hoạt động vì (1) UrlPathEncode không chạm vào bất cứ thứ gì sau đó ?và (2) UrlPathEncode &dù sao cũng không mã hóa .
Tim Goodman

1
Xem ở đây: connect.microsoft.com/VisualStudio/feedback/details/551839/... tôi nên thêm rằng tất nhiên nó tốt mà UrlPathEncode không thực hiện mã hóa &, bởi vì bạn cần điều đó để phân định các thông số chuỗi truy vấn của bạn. Nhưng có những lúc bạn muốn ampersands được mã hóa là tốt.
Tim Goodman

10
HttpUtility được thành công bởi WebUtility trong các phiên bản mới nhất, hãy tiết kiệm thời gian cho mình :)
Wiseman

189

Cách tốt hơn là sử dụng

Uri.EscapeUriString

để không tham khảo Hồ sơ đầy đủ của .net 4.


1
Hoàn toàn đồng ý vì thường thì "Hồ sơ khách hàng" là đủ cho các ứng dụng sử dụng System.Net nhưng không sử dụng System.Web ;-)
hfrmobile

6
OP đang nói về việc kiểm tra tính tương thích của hệ thống tệp, vì vậy điều này sẽ không hoạt động. Bộ ký tự không được phép của Windows là '["/", "\\", "<", ">", ":", "\" "," | ","? "," * "]' Nhưng nhiều trong số này không được mã hóa bằng EscopedUriString (xem bảng bên dưới - cảm ơn vì bảng đó @Simon Tewsi) ... "tạo đường dẫn trên máy cục bộ của họ" -OP UrlEncoding xử lý gần như tất cả các vấn đề, nhưng không giải quyết được vấn đề với "%" hoặc "% 3f" nằm ở đầu vào ban đầu, vì "giải mã" bây giờ sẽ khác so với ban đầu.
m1m1k

6
chỉ để làm rõ: Câu trả lời NÀY KHÔNG LÀM VIỆC cho các hệ thống tệp
m1m1k

1
Ngoài ra, bắt đầu với .NET Framework 4.5, Hồ sơ khách hàng đã bị ngừng và chỉ có gói có thể phân phối lại đầy đủ.
twomm

29
stackoverflow.com/a 432189188 43236164 Sử dụng Uri.EscapeDataStringKHÔNG Uri.EscapeUriStringĐọc bình luận này, nó đã giúp tôi ra ngoài.
ykadaru

181

.NET Framework 4.5.NET Standard 1.0, bạn nên sử dụng WebUtility.UrlEncode. Ưu điểm so với các lựa chọn thay thế:

  1. Nó là một phần của .NET Framework 4.5+, .NET Core 1.0+, .NET Standard 1.0+, UWP 10.0+ và tất cả các nền tảng Xamarin. HttpUtility, mặc dù có sẵn trong .NET Framework trước đó (.NET Framework 1.1+), sẽ có sẵn trên các nền tảng khác muộn hơn (.NET Core 2.0+, .NET Standard 2.0+) và nó vẫn không khả dụng trong UWP (xem câu hỏi liên quan ).

  2. Trong .NET Framework, nó nằm trong đóSystem.dll , vì vậy nó không yêu cầu bất kỳ tham chiếu bổ sung nào, không giống như HttpUtility.

  3. thoát đúng các ký tự cho URL , không giống như Uri.EscapeUriString(xem bình luận cho câu trả lời của drweb86 ).

  4. không có bất kỳ giới hạn nào về độ dài của chuỗi , không giống như Uri.EscapeDataString(xem câu hỏi liên quan ), vì vậy nó có thể được sử dụng cho các yêu cầu POST chẳng hạn.


Tôi thích cách nó mã hóa bằng cách sử dụng "+" thay vì% 20 cho dấu cách .. nhưng cái này vẫn không xóa "khỏi URL và cung cấp cho tôi URL không hợp lệ ... ồ tốt .. tôi sẽ phải thay thế (" "" "", "")
Piotr Kula

84

Levi Botelho nhận xét rằng bảng mã hóa được tạo trước đó không còn chính xác cho .NET 4.5, vì mã hóa thay đổi một chút giữa .NET 4.0 và 4.5. Vì vậy, tôi đã tạo lại bảng cho .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]

Các cột biểu thị mã hóa như sau:

  • Mã hóa: HttpUtility.UrlEncode
  • UrlEncodingUnicode: HttpUtility.UrlEncodeUnicode
  • UrlPathEncoding: HttpUtility.UrlPathEncode
  • WebUtilityUrlEncoding: WebUtility.UrlEncode
  • Đã thoátDataString: Uri.EscapeDataString
  • EscgedUriString: Uri.EscapeUriString
  • HtmlEncoding: HttpUtility.HtmlEncode
  • HtmlAttributionEncoding: HttpUtility.HtmlAttributeEncode
  • WebUtilityHtmlĐược mã hóa: WebUtility.HtmlEncode
  • HexEscoped: Uri.HexEscape

GHI CHÚ:

  1. HexEscape chỉ có thể xử lý 255 ký tự đầu tiên. Do đó, nó đưa ra một ngoại lệ ArgumentOutOfRange cho các ký tự A-Extended Latin (ví dụ).

  2. Bảng này được tạo trong .NET 4.5 (xem câu trả lời https://stackoverflow.com/a/11236038/216440 để biết các bảng mã có liên quan đến .NET 4.0 trở xuống).

BIÊN TẬP:

  1. Do câu trả lời của Discord, tôi đã thêm các phương thức WebUtility UrlEncode và HtmlEncode mới, được giới thiệu trong .NET 4.5.

2
Không không phải người dùng UrlPathEncode - ngay cả MSDN cũng nói rằng nó không được sử dụng. Nó được xây dựng để khắc phục sự cố với Netscape 2 msdn.microsoft.com/en-us/l Library / Kẻ
Jeff

Server.URLEncode có phải là một biến thể khác của chủ đề này không? Nó tạo ra bất kỳ đầu ra khác nhau?
ALEXintlsos

2
@ALEX: Trong ASP.NET, đối tượng Server là một thể hiện của HTTPServerUtility. Sử dụng trình dịch ngược dotPeek tôi đã xem qua httpServerUtility.UrlEncode. Nó chỉ gọi httpUtility.UrlEncode để đầu ra của hai phương thức sẽ giống hệt nhau.
Simon Tewsi

Có vẻ như, ngay cả với sự dư thừa của các phương thức mã hóa này, tất cả chúng vẫn thất bại khá ngoạn mục đối với bất kỳ thứ gì trên Latin-1, chẳng hạn như → hoặc. (UrlEncodingUnicode có vẻ như ít nhất là cố gắng hỗ trợ Unicode, nhưng không được chấp nhận / bị thiếu.)
brianary

Simon, bạn có thể tích hợp câu trả lời này trong câu trả lời được chấp nhận không? nó sẽ được tốt đẹp để có nó trong một câu trả lời. bạn có thể tích hợp nó và tạo một tiêu đề h1 ở cuối câu trả lời hoặc tích hợp trong một bảng và đánh dấu các dòng khác nhau, như: (Net4.0) ? %3f................................ (Net4.5) ? %3f ..................................
T.Todua

60

Mã hóa Url dễ dàng trong .NET. Sử dụng:

System.Web.HttpUtility.UrlEncode(string url)

Nếu điều đó sẽ được giải mã để lấy tên thư mục, bạn vẫn sẽ cần loại trừ các ký tự không thể được sử dụng trong tên thư mục (*,?, /, V.v.)


Liệu nó mã hóa mọi ký tự không phải là một phần của bảng chữ cái?
masfenix

1
Mã hóa URL chuyển đổi các ký tự không được phép trong URL thành tương đương thực thể ký tự. Danh sách các ký tự không an toàn: blooberry.com/indexdot/html/topics/urlencoding.htmlm
Ian Robinson

Liên kết MSDN trên HttpUtility.UrlEncode: msdn.microsoft.com/en-us/l
Ian Robinson

11
Đó là một thực hành tốt để đặt toàn bộ System.Web ... trong câu trả lời của bạn, nó giúp tiết kiệm rất nhiều người một chút thời gian :) cảm ơn
Liam

3
Điều này rất nguy hiểm: không phải tất cả các ký tự của url phải được mã hóa, chỉ các giá trị của các tham số của chuỗi truy vấn. Cách bạn đề xuất cũng sẽ mã hóa & cần thiết để tạo nhiều tham số trong chuỗi truy vấn. Hướng dẫn là mã hóa từng giá trị của các tham số nếu cần
Marco Staffoli

12

Nếu bạn không thể thấy System.Web, hãy thay đổi cài đặt dự án của bạn. Khung mục tiêu phải là ".NET Framework 4" thay vì ".NET Framework 4 Client Profile"


1
Theo tôi, các nhà phát triển nên biết về "Hồ sơ .NET" và họ nên sử dụng đúng cho mục đích của họ! Chỉ cần thêm hồ sơ đầy đủ để có được (ví dụ System.Web) mà không thực sự biết lý do tại sao họ thêm hồ sơ đầy đủ, không phải là rất thông minh. Sử dụng "Hồ sơ khách hàng" cho các ứng dụng khách của bạn và hồ sơ đầy đủ chỉ khi cần thiết (ví dụ: ứng dụng khách WinForms hoặc WPF nên sử dụng hồ sơ khách hàng và không phải hồ sơ đầy đủ)! ví dụ: tôi không thấy lý do sử dụng HTTPServerUtility trong ứng dụng khách ^^ ... nếu điều này là cần thiết thì có gì đó không đúng với thiết kế của ứng dụng!
hfrmobile

4
Có thật không? Bạn chưa bao giờ thấy cần một ứng dụng khách để tạo URL? Bạn làm gì để kiếm sống - nhiệm vụ của người gác cổng?
sproketboy

@hfrmobile: không. Tất cả đều sai với mô hình hồ sơ (chỉ sống một lần và bị bỏ rơi trong phiên bản tiếp theo). Và nó đã rõ ràng ngay từ đầu. Nó là rõ ràng cho bạn bây giờ? Hãy suy nghĩ trước, đừng chấp nhận mọi thứ 'như là' những gì msft cố gắng bán cho bạn; P
abatishchev

Xin lỗi, nhưng tôi chưa bao giờ nói rằng khách hàng không bao giờ phải xây dựng / sử dụng URL. Miễn là .NET 4.0 được sử dụng, người dùng nên quan tâm đến nó. Nói ngắn gọn: Các nhà phát triển nên suy nghĩ kỹ trước khi thêm httpServerUtility vào máy khách. Có nhiều cách khác / tốt hơn, chỉ cần xem câu trả lời với 139 phiếu hoặc "Vì .NET Framework 4.5, bạn có thể sử dụng WebUtility.UrlEncode. Đầu tiên, nó nằm trong System.dll, vì vậy nó không yêu cầu bất kỳ tài liệu tham khảo bổ sung nào."
hfrmobile

9

Việc triển khai .NET UrlEncodekhông tuân thủ RFC 3986.

  1. Một số ký tự không được mã hóa nhưng nên được. Các !()*ký tự được liệt kê trong phần 2.2 của RFC là một ký tự dành riêng phải được mã hóa nhưng .NET không thể mã hóa các ký tự này.

  2. Một số ký tự được mã hóa nhưng không nên. Các .-_ký tự không được liệt kê trong phần 2.2 của RFC là một ký tự dành riêng chưa được mã hóa. .NET đã mã hóa sai các ký tự này.

  3. RFC chỉ định rằng để thống nhất, việc triển khai nên sử dụng HEXDIG chữ hoa, trong đó .NET tạo HEXDIG chữ thường.


4

Tôi nghĩ mọi người ở đây đã bị lãng quên bởi thông điệp UrlEncode. URLEncoding không những gì bạn muốn - bạn muốn mã hóa những thứ không hoạt động như một tên tệp trên hệ thống đích.

Giả sử rằng bạn muốn một số tính tổng quát - thoải mái tìm các ký tự không hợp lệ trên một số hệ thống (MacOS, Windows, Linux và Unix), liên kết chúng để tạo thành một bộ ký tự để thoát.

Đối với lối thoát, HexEscape sẽ ổn (Thay thế các ký tự bằng% XX). Chuyển đổi từng ký tự thành các byte UTF-8 và mã hóa mọi thứ> 128 nếu bạn muốn hỗ trợ các hệ thống không thực hiện unicode. Nhưng có nhiều cách khác, chẳng hạn như sử dụng dấu gạch chéo ngược "\" hoặc mã hóa HTML "" ". Bạn có thể tự tạo. Tất cả mọi hệ thống phải làm là" mã hóa "ký tự không tương thích đi. Các hệ thống trên cho phép bạn tạo lại tên gốc - nhưng một cái gì đó như thay thế các ký tự xấu bằng dấu cách cũng hoạt động.

Trên cùng một tiếp tuyến như trên, người duy nhất sử dụng là

Uri.EscapeDataString

- Nó mã hóa mọi thứ cần thiết cho OAuth, nó không mã hóa những thứ mà OAuth cấm mã hóa và mã hóa không gian dưới dạng% 20 và không + (Ngoài ra trong Thông số OATH) Xem: RFC 3986. AFAIK, đây là thông số URI mới nhất.


3

Tôi đã viết một phương thức C # mã hóa url TẤT CẢ các ký hiệu:

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

Lý tưởng nhất là chúng sẽ đi trong một lớp gọi là "FileNaming" hoặc có thể chỉ đổi tên Encode thành "FileNameEncode". Lưu ý: những mục này không được thiết kế để xử lý Đường dẫn đầy đủ, chỉ thư mục và / hoặc tên tệp. Lý tưởng nhất là bạn sẽ phân tách ("/") đường dẫn đầy đủ của bạn trước và sau đó kiểm tra các mảnh. Và rõ ràng thay vì liên minh, bạn chỉ có thể thêm ký tự "%" vào danh sách các ký tự không được phép trong Windows, nhưng tôi nghĩ nó hữu ích / dễ đọc / thực tế hơn theo cách này. Giải mã () hoàn toàn giống nhau nhưng chuyển "Thay thế" (Uri.HexEscape (s [0]), s) "thoát" với ký tự.

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

Cảm ơn @ simon-tewsi cho bảng rất hữu ích ở trên!


cũng hữu ích: Path.GetInvalidFileNameChars()
m1m1k

Đúng. Đây là một cách để làm điều đó: foreach (char c trong System.IO.Path.GetInvalidFileNameChars ()) {filename = filename.Replace (c, '_'); }
netfed

0

Ngoài câu trả lời của @Dan Herbert, Bạn nên mã hóa các giá trị nói chung.

Split có tham số params Split ('&', '='); biểu thức trước hết được phân tách bởi & then '=' vì vậy các phần tử lẻ là tất cả các giá trị được mã hóa được hiển thị bên dưới.

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);
        }
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.