使用C#进行URL编码

464

我有一个应用程序,它向VB论坛软件发送POST请求并登录用户(不设置cookie或其他任何内容)。

一旦用户登录成功,我创建一个变量,在他们的本地计算机上创建一个路径。

c:\ tempfolder \ date \ username

问题是有些用户名会抛出“非法字符”异常。例如,如果我的用户名是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 值或任何能轻松识别该字符的值。


将以下内容纳入以使文件系统安全文件夹名称:https://dev59.com/j3RC5IYBdhLWcg3wVvYt - missaghi
14个回答

724

我一直在尝试使用.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 异常。

  2. 此表格在 .NET 4.0 中生成 (请参见下面 Levi Botelho 的评论,.NET 4.5 中的编码略有不同)。

编辑:

我已经添加了第二个表格,其中包含 .NET 4.5 的编码。请参阅此答案:https://dev59.com/FnRB5IYBdhLWcg3wl4Sc#21771206

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

点击此处在dotnetfiddle.net上运行代码


请注意,.NET文档中指出“不要使用;仅用于浏览器兼容性。使用UrlEncode。”但是该方法会编码许多其他不需要的字符。最接近的方法是Uri.EscapeUriString,但要注意它不支持null参数。 - Andrew
1
我忘了提到,我上面的评论是针对 UrlPathEncode 的。因此,基本上将 UrlPathEncode 替换为 Uri.EscapeUriString 即可。 - Andrew
1
注意:这个答案是误导性的。一些转义方法根据字符串中的上下文而转义不同的字符。如果你不完全理解它们的限制,有些方法是非常危险的。如果你要把东西放到URI里,请使用Uri.EscapeDataString(而不是EscapeUriString!),除非你非常确定自己知道在做什么。 - Eamon Nerbonne
.NET Core 3+和.NET 5有什么变化吗? - huang
2
HTML标准对URL中“?”字符后的查询参数使用略有不同的编码。在“?”之前,使用URI百分比编码。在“?”之后,使用“application/x-www-form-urlencoded”编码。特别是这就是为什么空格在“?”之前被编码为%20,但在“?”之后被编码为+的原因。请注意,URLEncoded将空格编码为+,而EscapedUriString将其编码为%20。请参阅HTML标准中的“Mutate action URL”和“application/x-www-form-urlencoded serializer”。 - user281806
你很少看到一个答案是一个资源 - 多么棒的答案。 - Shewan

332

你应该只编码用户名或者其他可能无效的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所提到的那样,您仍需要确保删除非法文件名字符,否则文件系统将无法识别该路径。


37
使用HttpUtility.UrlPathEncode方法可以避免你在这里描述的问题。 - vipirtti
14
@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根本不编码“&”。 - Tim Goodman
1
请参见:http://connect.microsoft.com/VisualStudio/feedback/details/551839/error-in-documentation-for-httpserverutility-urlpathencode当然,UrlPathEncode不编码&是很好的,因为您需要它来分隔查询字符串参数。但有时您也需要编码的“&”。 - Tim Goodman
12
在最新版本中,HttpUtility 已被 WebUtility 替代,这样可以节省您的时间 :) - Wiseman

230

1
完全同意,因为使用 System.Net 而不使用 System.Web 的应用程序通常只需要“客户端配置文件”;-) - hfrmobile
7
OP在谈论检查文件系统兼容性,因此这样做行不通。Windows禁止使用的字符集为'["/","\","<",">",":","","|","?","*"]',但其中许多字符在使用EscapedUriString进行编码时并没有被编码(请参考下表 - 感谢@Simon Tewsi提供了该表)。“在本地机器上创建路径”-OPUrlEncoded几乎可以解决所有问题,但无法解决输入中包含“%”或“%3f”的问题,因为解码后将与原始输入不同。 - m1m1k
7
明确一下:此答案不适用于文件系统。 - m1m1k
1
此外,从.NET Framework 4.5开始,客户端配置文件已被停用,只提供完整的可再分发包。 - twomm
49
使用 Uri.EscapeDataString 而不是 Uri.EscapeUriString。阅读这条评论,它对我很有帮助。 - ykadaru

211
自从 .NET Framework 4.5 和 .NET Standard 1.0 版本以后,你应该使用 WebUtility.UrlEncode。相比其他替代方案,它具有以下优点:
  1. 它是.NET Framework 4.5+、.NET Core 1.0+、.NET Standard 1.0+、UWP 10.0+和所有Xamarin平台的一部分。HttpUtility虽然在较早的.NET Framework (.NET Framework 1.1+)中就已经可用了,但在其他平台上出现得要晚得多(.NET Core 2.0+、.NET Standard 2.0+),而且在UWP中仍然不可用(请参见related question)。

  2. 在.NET Framework中,它位于System.dll中,因此不需要任何其他引用,不像HttpUtility

  3. 正确转义URL字符,而不像Uri.EscapeUriString(请参见comments to drweb86's answer)。

  4. 没有字符串长度限制,而不像Uri.EscapeDataString(请参见related question),因此可以用于POST请求等。


1
我喜欢它使用“+”而不是%20来编码空格的方式...但这个仍然没有从URL中删除引号并给了我无效的URL...好吧...只能使用replace(""""","")进行替换。 - Piotr Kula

209

编辑:请注意,本答案已经过时。请参见下面的Siarhei Kuchuk的答案以获得更好的解决方案。

UrlEncoding会执行您在此处建议的操作。在C#中,您只需使用HttpUtility即可,如上所述。

您还可以正则表达式匹配非法字符,然后进行替换,但这将变得更加复杂,因为您将不得不有某种形式的状态机(例如switch ... case)来替换正确的字符。由于UrlEncode在前面就完成了这一点,因此它相当容易。

至于Linux与Windows之间的区别,有一些字符在Linux中是可接受的,而在Windows中则不是,但我不会担心这个问题,因为文件夹名称可以通过对Url字符串进行解码并使用UrlDecode来返回,因此您可以很轻松地进行往返更改。


5
这个答案现在已经过时了。请阅读下面几个答案——截至 .NET 4.5 版本,这可能是正确的解决方案:http://msdn.microsoft.com/en-us/library/system.net.webutility.urlencode.aspx。 - blueberryfields
1
对于FTP,每个Uri部分(文件夹或文件名)都可以使用Uri.EscapeDataString(fileOrFolderName)构建,从而允许所有非Uri兼容字符(空格,Unicode ...)。例如,为了允许文件名中的任何字符,请使用:req =(FtpWebRequest)WebRequest.Create(new Uri(path +“/”+ Uri.EscapeDataString(filename))); 使用HttpUtility.UrlEncode()将空格替换为加号(+)。这是搜索引擎的正确行为,但对于文件/文件夹名称则不正确。 - Renaud Bancel
asp.net在URL中阻止大部分XSS攻击,因为每当您尝试添加JS脚本时,您会收到警告“检测到来自客户端的潜在危险的Request.Path值”。 - Learning

104

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 个字符。因此对于拉丁语 A-Extended 字符(例如 Ā)抛出 ArgumentOutOfRange 异常。

  2. 此表格是在 .NET 4.5 中生成的(有关 .NET 4.0 及以下版本相关的编码,请参见答案https://dev59.com/FnRB5IYBdhLWcg3wl4Sc#11236038)。

编辑:

  1. 根据 Discord 的回答,我添加了新的 WebUtility UrlEncode 和 HtmlEncode 方法,这些方法是在 .NET 4.5 中引入的。

2
不要使用UrlPathEncode - 即使MSDN也说不应该使用它。它是为了解决Netscape 2的问题而构建的。http://msdn.microsoft.com/en-us/library/system.web.httpserverutility.urlpathencode(v=vs.110).aspx - Jeff
Server.URLEncode是这个主题的另一种变体吗?它会生成任何不同的输出吗? - ALEXintlsos
2
@ALEX:在ASP.NET中,Server对象是HttpServerUtility的一个实例。使用dotPeek反编译器,我查看了HttpServerUtility.UrlEncode。它只是调用HttpUtility.UrlEncode,因此这两种方法的输出将是相同的。 - Simon Elms
1
似乎即使有这么多编码方法,它们在处理超过Latin-1的字符时仍然表现得相当糟糕,例如→或☠。(UrlEncodedUnicode似乎至少尝试支持Unicode,但已被弃用/缺失。) - brianary
Simon,你能把这个回答集成到已被接受的答案中吗?将其放在一个答案中会更好。你可以把它集成在底部并添加一个h1标题,或者将其集成在一个表格中,并标记不同的行,如下所示:(Net4.0) ? %3f................................ (Net4.5) ? %3f .................................. - T.Todua
伤心啊,我需要把单引号 ' 转换为 '',把等于号 = 转换为 %3D,把空格转换为 %20。但是我不想升级到4.0版本。 - Trương Quốc Khánh

75

.NET 中的 URL 编码很容易。使用:

System.Web.HttpUtility.UrlEncode(string url)

如果要解码并获取文件夹名称,您仍需要排除无法用作文件夹名称的字符(*、?、/ 等等)。


它是否对不属于字母表的每个字符进行编码? - masfenix
2
URL编码将在URL中不允许的字符转换为字符实体等价物。不安全字符列表:http://www.blooberry.com/indexdot/html/topics/urlencoding.htm - Ian Robinson
HttpUtility.UrlEncode的MSDN链接:http://msdn.microsoft.com/en-us/library/4fkewx0t.aspx - Ian Robinson
14
在您的回答中使用完整的 System.Web... 部分是一个好的实践,这可以为许多人节省一些时间 :) 谢谢。 - Liam
4
这很危险:并非所有URL字符都需要编码,只有查询字符串参数的值需要编码。您提出的方法也会编码“&”,而这个符号在查询字符串中用于创建多个参数。 解决方案是根据需要对每个参数的值进行编码。 - Marco Staffoli

12

如果您无法看到 System.Web,请更改项目设置。目标框架应为“.NET Framework 4”,而不是“.NET Framework 4 客户端配置文件”。


1
在我看来,开发人员应该了解“.NET配置文件”,并且他们应该为自己的目的使用正确的配置文件!仅仅添加完整的配置文件以获取(例如System.Web),而不真正知道为什么添加完整的配置文件,这并不是很聪明。对于您的客户端应用程序,请使用“客户端配置文件”,仅在需要时使用完整的配置文件(例如WinForms或WPF客户端应使用客户端配置文件而不是完整的配置文件)!例如,我不认为在客户端应用程序中使用HttpServerUtility有任何理由^^...如果需要,则说明应用程序的设计存在问题! - hfrmobile
4
真的吗?你从来没有看到客户端应用程序需要构建URL的必要性吗?你是做清洁工作的吗? - sproketboy
@hfrmobile:不,关于配置文件模型的一切都是错误的(它只存在一次,并在下一个版本中被放弃了)。这从一开始就很明显。现在对你来说也很明显吗?首先要思考,不要接受微软试图向你推销的所有东西;P - abatishchev
抱歉,但我从未说过客户端永远不必构建/使用URL。只要使用.NET 4.0,用户就应该关心它。简而言之:开发人员在向客户端添加HttpServerUtility之前应三思。还有其他更好的方法,请参见得到139票的答案或“自.NET Framework 4.5以来,您可以使用WebUtility.UrlEncode。首先,它驻留在System.dll中,因此不需要任何其他引用。”。 - hfrmobile

10

.NET实现的UrlEncode不符合RFC 3986规范。

  1. 有些字符没有被编码,但是应该进行编码。RFC 2.2章节列出了!()*字符作为必须编码的保留字符,但是.NET未对这些字符进行编码。

  2. 有些字符已经被编码,但是不应该进行编码。RFC 2.2章节未将.-_字符列为不应该编码的保留字符,但是.NET错误地对这些字符进行了编码。

  3. RFC规定为保持一致性,实现应使用大写HEXDIG,而.NET产生小写HEXDIG。


6
我认为在UrlEncode信息中人们被引入了歧途。URLEncoding并不是你想要的——你需要对目标系统上无法作为文件名的内容进行编码。
假设你想要一些通用性,可以随意找到几个系统(MacOS,Windows,Linux和Unix)上的非法字符,将它们合并形成一个需要转义的字符集。
至于转义,十六进制转义应该就可以了(用%XX替换字符)。如果你想支持不支持Unicode的系统,请将每个字符转换为UTF-8字节,并编码所有大于128的内容。但也有其他方法,比如使用反斜杠“\”或HTML编码“”。你可以自己创建方法。任何系统都只需要'编码'掉不兼容的字符。上述系统允许您重新创建原始名称,但像用空格替换坏字符这样的方法也可以工作。
沿着上述思路,唯一要使用的是
Uri.EscapeDataString
——它编码了OAuth所需的所有内容,不会编码OAuth禁止编码的内容,并将空格编码为%20而不是+(也在OATH规范中)。请参阅:RFC 3986。据我所知,这是最新的URI规范。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接