การเข้ารหัส URL โดยใช้ C #


340

ฉันมีแอปพลิเคชันซึ่งส่งคำขอ POST ไปยังซอฟต์แวร์ฟอรัม VB และบันทึกบางคนใน

เมื่อผู้ใช้เข้าสู่ระบบฉันสร้างตัวแปรที่สร้างเส้นทางบนเครื่องของพวกเขา

C: \ tempfolder \ วัน \ ชื่อผู้ใช้

ปัญหาคือชื่อผู้ใช้บางรายกำลังมีข้อยกเว้น "ตัวอักษรที่ผิดกฎหมาย" ตัวอย่างเช่นถ้าชื่อผู้ใช้ของฉันmas|fenixมันจะเป็นข้อยกเว้น ..

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

ฉันไม่ต้องการลบออกจากสตริง แต่โฟลเดอร์ที่มีชื่อผู้ใช้จะถูกสร้างขึ้นผ่าน FTP บนเซิร์ฟเวอร์ และนี่นำไปสู่คำถามที่สองของฉัน หากฉันกำลังสร้างโฟลเดอร์บนเซิร์ฟเวอร์ฉันสามารถปล่อย "ตัวอักษรที่ผิดกฎหมาย" ไว้ได้หรือไม่? ฉันถามสิ่งนี้เพราะเซิร์ฟเวอร์ใช้ Linux และฉันไม่แน่ใจว่า Linux ยอมรับหรือไม่

แก้ไข: ดูเหมือนว่าการเข้ารหัส URL ไม่ใช่สิ่งที่ฉันต้องการ .. นี่คือสิ่งที่ฉันต้องการจะทำ:

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

โดยที่% xx คือค่า ASCII หรือค่าอื่น ๆ ที่สามารถระบุตัวละครได้อย่างง่ายดาย


รวมสิ่งนี้เพื่อสร้างชื่อโฟลเดอร์ระบบไฟล์ที่ปลอดภัย: http://stackoverflow.com/questions/333175/is-there-a-way-of-making-strings-file-path-safe-in-c
missaghi

คำตอบ:


191

แก้ไข: โปรดทราบว่าคำตอบนี้ล้าสมัยแล้ว ดูคำตอบของ Siarhei Kuchuk ด้านล่างเพื่อการแก้ไขที่ดีกว่า

UrlEncoding จะทำสิ่งที่คุณแนะนำที่นี่ ด้วย C # คุณสามารถใช้งานHttpUtilityได้ตามที่กล่าวไว้

นอกจากนี้คุณยังสามารถ Regex อักขระผิดกฎหมายแล้วแทนที่ แต่สิ่งนี้มีความซับซ้อนมากกว่าเนื่องจากคุณจะต้องมีรูปแบบของเครื่องสถานะ (ตัวอย่างเช่น ... กรณี) เพื่อแทนที่ด้วยอักขระที่ถูกต้อง ตั้งแต่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 (filename)); ใช้ HttpUtility.UrlEncode () แทนที่ช่องว่างด้วยเครื่องหมายบวก (+) พฤติกรรมที่ถูกต้องสำหรับเครื่องมือค้นหา แต่ไม่ถูกต้องสำหรับชื่อไฟล์ / โฟลเดอร์
Renaud Bancel

asp.net บล็อกส่วนใหญ่ของ XSS ใน URL A potentially dangerous Request.Path value was detected from the clientที่คุณได้รับการเตือนเมื่อคุณเคยพยายามที่จะเพิ่มสคริปต์
เรียนรู้

511

ฉันได้ทำการทดลองด้วยวิธีการต่าง ๆ ที่. 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 (ดูความคิดเห็นของ Levi Botelho ด้านล่างที่ระบุว่าการเข้ารหัสใน. NET 4.5 แตกต่างกันเล็กน้อย)

แก้ไข:

ฉันได้เพิ่มตารางที่สองพร้อมการเข้ารหัสสำหรับ. NET 4.5 ดูคำตอบนี้: https://stackoverflow.com/a/21771206/216440

แก้ไข 2:

เนื่องจากคนดูเหมือนจะชื่นชมตารางเหล่านี้ฉันคิดว่าคุณอาจชอบซอร์สโค้ดที่สร้างตารางเพื่อให้คุณสามารถเล่นกับตัวเอง มันเป็นแอพพลิเคชั่นคอนโซล C # ที่ใช้งานง่ายซึ่งสามารถกำหนดเป้าหมายเป็น. NET 4.0 หรือ 4.5

using System;
using System.Collections.Generic;
using System.Text;
// Need to add a Reference to the System.Web assembly.
using System.Web;

namespace UriEncodingDEMO2
{
    class Program
    {
        static void Main(string[] args)
        {
            EncodeStrings();

            Console.WriteLine();
            Console.WriteLine("Press any key to continue...");
            Console.Read();
        }

        public static void EncodeStrings()
        {
            string stringToEncode = "ABCD" + "abcd"
            + "0123" + " !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + "ĀāĒēĪīŌōŪū";

            // Need to set the console encoding to display non-ASCII characters correctly (eg the 
            //  Latin A-Extended characters such as ĀāĒē...).
            Console.OutputEncoding = Encoding.UTF8;

            // Will also need to set the console font (in the console Properties dialog) to a font 
            //  that displays the extended character set correctly.
            // The following fonts all display the extended characters correctly:
            //  Consolas
            //  DejaVu Sana Mono
            //  Lucida Console

            // Also, in the console Properties, set the Screen Buffer Size and the Window Size 
            //  Width properties to at least 140 characters, to display the full width of the 
            //  table that is generated.

            Dictionary<string, Func<string, string>> columnDetails =
                new Dictionary<string, Func<string, string>>();
            columnDetails.Add("Unencoded", (unencodedString => unencodedString));
            columnDetails.Add("UrlEncoded",
                (unencodedString => HttpUtility.UrlEncode(unencodedString)));
            columnDetails.Add("UrlEncodedUnicode",
                (unencodedString => HttpUtility.UrlEncodeUnicode(unencodedString)));
            columnDetails.Add("UrlPathEncoded",
                (unencodedString => HttpUtility.UrlPathEncode(unencodedString)));
            columnDetails.Add("EscapedDataString",
                (unencodedString => Uri.EscapeDataString(unencodedString)));
            columnDetails.Add("EscapedUriString",
                (unencodedString => Uri.EscapeUriString(unencodedString)));
            columnDetails.Add("HtmlEncoded",
                (unencodedString => HttpUtility.HtmlEncode(unencodedString)));
            columnDetails.Add("HtmlAttributeEncoded",
                (unencodedString => HttpUtility.HtmlAttributeEncode(unencodedString)));
            columnDetails.Add("HexEscaped",
                (unencodedString
                    =>
                    {
                        // Uri.HexEscape can only handle the first 255 characters so for the 
                        //  Latin A-Extended characters, such as A, it will throw an 
                        //  ArgumentOutOfRange exception.                       
                        try
                        {
                            return Uri.HexEscape(unencodedString.ToCharArray()[0]);
                        }
                        catch
                        {
                            return "[OoR]";
                        }
                    }));

            char[] charactersToEncode = stringToEncode.ToCharArray();
            string[] stringCharactersToEncode = Array.ConvertAll<char, string>(charactersToEncode,
                (character => character.ToString()));
            DisplayCharacterTable<string>(stringCharactersToEncode, columnDetails);
        }

        private static void DisplayCharacterTable<TUnencoded>(TUnencoded[] unencodedArray,
            Dictionary<string, Func<TUnencoded, string>> mappings)
        {
            foreach (string key in mappings.Keys)
            {
                Console.Write(key.Replace(" ", "[space]") + " ");
            }
            Console.WriteLine();

            foreach (TUnencoded unencodedObject in unencodedArray)
            {
                string stringCharToEncode = unencodedObject.ToString();
                foreach (string columnHeader in mappings.Keys)
                {
                    int columnWidth = columnHeader.Length + 1;
                    Func<TUnencoded, string> encoder = mappings[columnHeader];
                    string encodedString = encoder(unencodedObject);

                    // ASSUMPTION: Column header will always be wider than encoded string.
                    Console.Write(encodedString.Replace(" ", "[space]").PadRight(columnWidth));
                }
                Console.WriteLine();
            }
        }
    }
}

2
นี่คือคำตอบที่ยอดเยี่ยม ปรากฎว่าฉันต้องการใช้ Uri.EscapeDataString และไม่รวม System.Web ขอบคุณสำหรับตารางนี้
Seravy

7
โปรดทราบว่านี่ไม่ถูกต้อง 100% อีกต่อไป ฟังก์ชันบางอย่างเปลี่ยนไปเล็กน้อยระหว่าง. NET 4 และ. NET 4.5 ดูstackoverflow.com/q/20003106/1068266
Levi Botelho

2
@Levi: ขอบคุณสำหรับหัวขึ้น ฉันได้เพิ่มคำตอบที่สองด้วยตารางสำหรับ. NET 4.5 ฉันได้แก้ไขคำตอบเดิมเพื่อเชื่อมโยงไปยังตารางที่สอง
Simon Tewsi

โปรดทราบว่า. NET เอกสารว่าอย่าใช้; มีไว้เพื่อความเข้ากันได้ของเบราว์เซอร์เท่านั้น ใช้ UrlEncode แต่วิธีการนั้นเข้ารหัสอักขระที่ไม่พึงประสงค์อื่น ๆ จำนวนมาก สิ่งที่ใกล้เคียงที่สุดคือUri.EscapeUriStringแต่ระวังว่ามันไม่สนับสนุนการnullโต้แย้ง
Andrew

1
UrlPathEncodeฉันลืมที่จะพูดถึงความคิดเห็นของฉันข้างต้นสำหรับ ดังนั้นโดยทั่วไปแทนที่ด้วยUrlPathEncode Uri.EscapeUriString
Andrew

279

คุณควรเข้ารหัสเฉพาะชื่อผู้ใช้หรือส่วนอื่น ๆ ของ URL ที่อาจไม่ถูกต้อง การเข้ารหัส URL URL อาจนำไปสู่ปัญหาเนื่องจากสิ่งนี้:

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

จะให้ผลผลิต

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

เห็นได้ชัดว่านี่จะไม่ทำงานได้ดี คุณควรเข้ารหัสเฉพาะค่าของคู่คีย์ / ค่าในสตริงการสืบค้นเท่านั้นดังนี้

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

หวังว่าจะช่วยได้ นอกจากนี้ตามที่กล่าวไว้ในteedyayคุณจะต้องตรวจสอบให้แน่ใจว่าลบตัวอักษรชื่อไฟล์ผิดกฎหมายมิฉะนั้นระบบไฟล์จะไม่ชอบพา ธ


34
การใช้เมธอด HttpUtility.UrlPathEncode ควรป้องกันปัญหาที่คุณกำลังอธิบายที่นี่
vipirtti

12
@DJ Pirtu: เป็นความจริงที่ว่า UrlPathEncode จะไม่ทำการเปลี่ยนแปลงที่ไม่พึงประสงค์เหล่านั้นในพา ธ อย่างไรก็ตามมันจะไม่เข้ารหัสอะไรหลังจาก?(เพราะถือว่าสตริงการสืบค้นถูกเข้ารหัสแล้ว) ในตัวอย่างของ Dan Herbert ดูเหมือนว่าเขาแสร้งทำเป็น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 มาตรฐาน 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 ที่ไม่ถูกต้องกับฉัน ... โอ้ดี .. เพียงแค่คุณต้องเปลี่ยน aa (" "" "", "")
Piotr Kula

85

Levi Botelho แสดงความคิดเห็นว่าตารางการเข้ารหัสที่สร้างไว้ก่อนหน้านี้ไม่ถูกต้องสำหรับ. NET 4.5 อีกต่อไปเนื่องจากการเข้ารหัสเปลี่ยนไปเล็กน้อยระหว่าง. NET 4.0 และ 4.5 ดังนั้นฉันจึงสร้างตารางสำหรับ. NET 4.5 ขึ้นใหม่:

Unencoded UrlEncoded UrlEncodedUnicode UrlPathEncoded WebUtilityUrlEncoded EscapedDataString EscapedUriString HtmlEncoded HtmlAttributeEncoded WebUtilityHtmlEncoded HexEscaped
A         A          A                 A              A                    A                 A                A           A                    A                     %41
B         B          B                 B              B                    B                 B                B           B                    B                     %42

a         a          a                 a              a                    a                 a                a           a                    a                     %61
b         b          b                 b              b                    b                 b                b           b                    b                     %62

0         0          0                 0              0                    0                 0                0           0                    0                     %30
1         1          1                 1              1                    1                 1                1           1                    1                     %31

[space]   +          +                 %20            +                    %20               %20              [space]     [space]              [space]               %20
!         !          !                 !              !                    %21               !                !           !                    !                     %21
"         %22        %22               "              %22                  %22               %22              &quot;      &quot;               &quot;                %22
#         %23        %23               #              %23                  %23               #                #           #                    #                     %23
$         %24        %24               $              %24                  %24               $                $           $                    $                     %24
%         %25        %25               %              %25                  %25               %25              %           %                    %                     %25
&         %26        %26               &              %26                  %26               &                &amp;       &amp;                &amp;                 %26
'         %27        %27               '              %27                  %27               '                &#39;       &#39;                &#39;                 %27
(         (          (                 (              (                    %28               (                (           (                    (                     %28
)         )          )                 )              )                    %29               )                )           )                    )                     %29
*         *          *                 *              *                    %2A               *                *           *                    *                     %2A
+         %2b        %2b               +              %2B                  %2B               +                +           +                    +                     %2B
,         %2c        %2c               ,              %2C                  %2C               ,                ,           ,                    ,                     %2C
-         -          -                 -              -                    -                 -                -           -                    -                     %2D
.         .          .                 .              .                    .                 .                .           .                    .                     %2E
/         %2f        %2f               /              %2F                  %2F               /                /           /                    /                     %2F
:         %3a        %3a               :              %3A                  %3A               :                :           :                    :                     %3A
;         %3b        %3b               ;              %3B                  %3B               ;                ;           ;                    ;                     %3B
<         %3c        %3c               <              %3C                  %3C               %3C              &lt;        &lt;                 &lt;                  %3C
=         %3d        %3d               =              %3D                  %3D               =                =           =                    =                     %3D
>         %3e        %3e               >              %3E                  %3E               %3E              &gt;        >                    &gt;                  %3E
?         %3f        %3f               ?              %3F                  %3F               ?                ?           ?                    ?                     %3F
@         %40        %40               @              %40                  %40               @                @           @                    @                     %40
[         %5b        %5b               [              %5B                  %5B               [                [           [                    [                     %5B
\         %5c        %5c               \              %5C                  %5C               %5C              \           \                    \                     %5C
]         %5d        %5d               ]              %5D                  %5D               ]                ]           ]                    ]                     %5D
^         %5e        %5e               ^              %5E                  %5E               %5E              ^           ^                    ^                     %5E
_         _          _                 _              _                    _                 _                _           _                    _                     %5F
`         %60        %60               `              %60                  %60               %60              `           `                    `                     %60
{         %7b        %7b               {              %7B                  %7B               %7B              {           {                    {                     %7B
|         %7c        %7c               |              %7C                  %7C               %7C              |           |                    |                     %7C
}         %7d        %7d               }              %7D                  %7D               %7D              }           }                    }                     %7D
~         %7e        %7e               ~              %7E                  ~                 ~                ~           ~                    ~                     %7E

Ā         %c4%80     %u0100            %c4%80         %C4%80               %C4%80            %C4%80           Ā           Ā                    Ā                     [OoR]
ā         %c4%81     %u0101            %c4%81         %C4%81               %C4%81            %C4%81           ā           ā                    ā                     [OoR]
Ē         %c4%92     %u0112            %c4%92         %C4%92               %C4%92            %C4%92           Ē           Ē                    Ē                     [OoR]
ē         %c4%93     %u0113            %c4%93         %C4%93               %C4%93            %C4%93           ē           ē                    ē                     [OoR]
Ī         %c4%aa     %u012a            %c4%aa         %C4%AA               %C4%AA            %C4%AA           Ī           Ī                    Ī                     [OoR]
ī         %c4%ab     %u012b            %c4%ab         %C4%AB               %C4%AB            %C4%AB           ī           ī                    ī                     [OoR]
Ō         %c5%8c     %u014c            %c5%8c         %C5%8C               %C5%8C            %C5%8C           Ō           Ō                    Ō                     [OoR]
ō         %c5%8d     %u014d            %c5%8d         %C5%8D               %C5%8D            %C5%8D           ō           ō                    ō                     [OoR]
Ū         %c5%aa     %u016a            %c5%aa         %C5%AA               %C5%AA            %C5%AA           Ū           Ū                    Ū                     [OoR]
ū         %c5%ab     %u016b            %c5%ab         %C5%AB               %C5%AB            %C5%AB           ū           ū                    ū                     [OoR]

คอลัมน์แสดงการเข้ารหัสดังนี้:

  • urlencoded: HttpUtility.UrlEncode
  • UrlEncodedUnicode: HttpUtility.UrlEncodeUnicode
  • UrlPathEncoded: HttpUtility.UrlPathEncode
  • WebUtilityUrlEncoded: WebUtility.UrlEncode
  • EscapedDataString: Uri.EscapeDataString
  • EscapedUriString: Uri.EscapeUriString
  • HtmlEncoded: HttpUtility.HtmlEncode
  • HtmlAttributeEncoded: HttpUtility.HtmlAttributeEncode
  • WebUtilityHtmlEncoded: WebUtility.HtmlEncode
  • HexEscaped: Uri.HexEscape

หมายเหตุ:

  1. HexEscape สามารถจัดการ 255 อักขระแรกเท่านั้น ดังนั้นมันจะโยนข้อยกเว้น ArgumentOutOfRange สำหรับอักขระละติน A-Extended (เช่นĀ)

  2. ตารางนี้สร้างขึ้นใน. NET 4.5 (ดูคำตอบhttps://stackoverflow.com/a/11236038/216440สำหรับการเข้ารหัสที่เกี่ยวข้องกับ. NET 4.0 และด้านล่าง)

แก้ไข:

  1. จากคำตอบของ Discord ฉันได้เพิ่มวิธีใหม่ของ WebUtility UrlEncode และ HtmlEncode ซึ่งถูกนำมาใช้ใน. NET 4.5

2
ไม่มีผู้ใช้ไม่ใช่ UrlPathEncode - แม้แต่ MSDN ก็บอกว่าไม่ควรใช้ มันถูกสร้างขึ้นเพื่อแก้ไขปัญหากับ netscape 2 msdn.microsoft.com/en-us/library/…
Jeff

Server.URLEncode เป็นรูปแบบอื่นของชุดรูปแบบนี้หรือไม่ มันสร้างผลลัพธ์ที่แตกต่างกันหรือไม่?
ALEXintlsos

2
@ALEX: ใน ASP.NET วัตถุเซิร์ฟเวอร์เป็นตัวอย่างของ HttpServerUtility การใช้เครื่องถอดรหัส dotPeek ฉันได้ดู HttpServerUtility.UrlEncode มันเพิ่งเรียก HttpUtility.UrlEncode ดังนั้นผลลัพธ์ของทั้งสองวิธีจะเหมือนกัน
Simon Tewsi

ดูเหมือนว่าแม้จะมีวิธีการเข้ารหัสมากเกินไปพวกเขาทั้งหมดก็ยังล้มเหลวอย่างงดงามสำหรับทุกอย่างที่เหนือละติน -1 เช่น→หรือ☠ (UrlEncodedUnicode ดูเหมือนว่าอย่างน้อยก็พยายามที่จะสนับสนุน Unicode แต่เลิกใช้ / ขาดหายไป)
brianary

Simon คุณสามารถรวมคำตอบนี้กับคำตอบที่ยอมรับได้ไหม มันจะดีถ้ามีในคำตอบเดียว คุณสามารถรวมมันและสร้างส่วนหัว 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
Ian Robinson

ลิงก์ MSDN บน HttpUtility.UrlEncode: msdn.microsoft.com/en-us/library/4fkewx0t.aspx
Ian Robinson

11
มันเป็นเรื่องที่ดีที่จะนำ System.Web เต็ม ... เป็นส่วนหนึ่งในคำตอบของคุณก็จะบันทึกจำนวนมากของผู้คนเวลาน้อย :) ขอบคุณ
เลียม

3
สิ่งนี้เป็นสิ่งที่อันตราย: ไม่สามารถเข้ารหัสอักขระทุกตัวได้เฉพาะค่าพารามิเตอร์ของการสอบถาม วิธีที่คุณแนะนำจะเข้ารหัสและ & ที่จำเป็นในการสร้างหลายพารามิเตอร์ในการสืบค้น soution คือการเข้ารหัสแต่ละค่าของพารามิเตอร์หากจำเป็น
Marco Staffoli

12

หากคุณไม่เห็น System.Web ให้เปลี่ยนการตั้งค่าโครงการของคุณ กรอบงานเป้าหมายควรเป็น ".NET Framework 4" แทน "โปรไฟล์ลูกค้า. NET Framework 4"


1
ในความเห็นของฉันนักพัฒนาควรรู้เกี่ยวกับ ". NET Profiles" และพวกเขาควรใช้ที่ถูกต้องเพื่อวัตถุประสงค์ของพวกเขา! เพียงแค่เพิ่มโปรไฟล์เต็มเพื่อรับ (เช่น System.Web) โดยไม่รู้ตัวว่าทำไมพวกเขาจึงเพิ่มโปรไฟล์เต็มไม่ใช่สมาร์ทมาก ใช้ "โปรไฟล์ลูกค้า" สำหรับแอปลูกค้าของคุณและโปรไฟล์เต็มรูปแบบเฉพาะเมื่อจำเป็น (เช่น WinForms หรือไคลเอ็นต์ WPF ควรใช้โปรไฟล์ลูกค้าและไม่ใช่โปรไฟล์เต็ม)! เช่นฉันไม่เห็นเหตุผลในการใช้ HttpServerUtility ในแอปไคลเอ็นต์ ^^ ... ถ้าจำเป็นนี่ก็มีบางอย่างผิดปกติกับการออกแบบแอพ!
hfrmobile

4
จริงๆ? ไม่เคยเห็นความต้องการแอปไคลเอนต์ในการสร้าง URL หรือไม่? คุณทำอะไรเพื่อการดำรงชีพ - หน้าที่ทำความสะอาด?
sproketboy

@hfrmobile: ไม่ ทุกอย่างผิดปกติกับโมเดลโปรไฟล์ (ซึ่งมีอยู่เพียงครั้งเดียวและถูกทอดทิ้งในเวอร์ชันถัดไป) และชัดเจนตั้งแต่ต้น ตอนนี้คุณชัดเจนหรือไม่? คิดก่อนอย่ายอมรับทุกอย่าง 'ตามที่เป็น' สิ่งที่ msft พยายามขายให้คุณ P
abatishchev

ขออภัยฉันไม่เคยพูดว่าลูกค้าไม่ต้องสร้าง / ใช้ 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 และไม่ใช่ + (ใน O Spec Spec) ดู: RFC 3986 AFAIK นี่คือ ข้อมูลจำเพาะ URI ล่าสุด


3

ฉันได้เขียนวิธี C # ที่ url-encodes สัญลักษณ์ทั้งหมด:

    /// <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" หรืออาจจะเปลี่ยนชื่อ Encode เป็น "FileNameEncode" หมายเหตุ: สิ่งเหล่านี้ไม่ได้ออกแบบมาเพื่อจัดการ Full Paths เพียงแค่ชื่อโฟลเดอร์และ / หรือชื่อไฟล์ เป็นการดีที่คุณจะแยก ("/") เส้นทางเต็มของคุณก่อนแล้วตรวจสอบชิ้นส่วน และชัดเจนกว่าการรวมกันคุณสามารถเพิ่มอักขระ "%" ลงในรายการตัวอักษรที่ไม่ได้รับอนุญาตใน Windows แต่ฉันคิดว่ามันมีประโยชน์มากขึ้น / อ่านได้ / เป็นจริงด้วยวิธีนี้ Decode () เหมือนกันทุกประการ แต่เปลี่ยน Replace (Uri.HexEscape (s [0]), s) "escaped" ด้วยอักขระ

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 คุณควรเข้ารหัสค่าโดยทั่วไป

แยกมีพารามิเตอร์พารามิเตอร์แยกส่วน ('&', '='); นิพจน์แยกก่อนโดย & จากนั้น '=' ดังนั้นองค์ประกอบที่แปลกคือค่าทั้งหมดที่จะเข้ารหัสแสดงด้านล่าง

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);
        }
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.