Server.UrlEncode与HttpUtility.UrlEncode

Man*_*anu 173 .net asp.net urlencode

Server.UrlEncode和HttpUtility.UrlEncode之间有区别吗?

Eam*_*nne 258

我之前对这些方法感到非常头疼,我建议你避免使用任何变体UrlEncode,而是使用Uri.EscapeDataString - 至少那个具有可理解的行为.

让我们来看看...

HttpUtility.UrlEncode(" ") == "+" //breaks ASP.NET when used in paths, non-
                                  //standard, undocumented.
Uri.EscapeUriString("a?b=e") == "a?b=e" // makes sense, but rarely what you
                                        // want, since you still need to
                                        // escape special characters yourself
Run Code Online (Sandbox Code Playgroud)

但我个人最喜欢的必须是HttpUtility.UrlPathEncode - 这件事真是难以理解.它编码:

  • ""==>"%20"
  • "100%true"==>"100 %% 20true"(好吧,你的网址现在坏了)
  • "test A.aspx#anchor B"==>"test%20A.aspx #anchor%20B "
  • "测试A.aspx?hmm#anchor B"==>"test%20A.aspx?hmm #anchor B "(注意与前一个转义序列的区别!)

它还具有可爱的MSDN文档"对URL字符串的路径部分进行编码,以便从Web服务器向客户端进行可靠的HTTP传输". - 没有实际解释它的作用.你不太可能用Uzi射击自己的脚...

简而言之,坚持使用Uri.EscapeDataString.

  • !并且'字符不应该被编码; 但如果一个有缺陷的网络服务器需要这个,那么很容易解决.避免使用javascript的转义函数 - 它本身就是错误的(不可能进行往返).请参阅http://xkr.us/articles/javascript/encode-compare/ - 但简而言之; 你可以使用encodeUriComponent(),它的行为类似于EscapeDataString - 它可以预测并可逆地编码一个字符串,也不编码!和'人物. (6认同)
  • 不幸的是,当对某些Web服务器执行HTTP请求时仍然无效 - Uri.EscapeDataString()不编码"!" 或"'",这与escape()的大多数浏览器实现的工作方式不同...... (3认同)
  • 这是旧的,但问题已经碰到了头版,所以....网址字符串的路径部分是域和?之间的部分.或#在网址中. (2认同)
  • @Tim:可能有几个`?`和谁说要编码哪个?哪个用作分隔符?至于空间:在这两种情况下,空间都在哈希中,因此查询片段的存在与否应该无关紧要.最后,在包含%的第二个例子中腐败一个Uri是不可原谅的.`urlPathEncode`方法是明确的,不应该使用. (2认同)

Meh*_*ari 132

HttpServerUtility.UrlEncode将在HttpUtility.UrlEncode内部使用.没有具体的区别.存在的原因Server.UrlEncode是与经典ASP的兼容性.

  • 至于什么被逃脱.在内部它调用这个函数http://referencesource.microsoft.com/#System/net/System/Net/WebUtility.cs,8caf12e95a01d73b (3认同)

Tod*_*ier 51

快进这个问题已经快9年了,在.NET Core和.NET Standard的世界里,我们对URL编码最常见的选择似乎是WebUtility.UrlEncode(下System.Net)和Uri.EscapeDataString.从这里和其他地方最流行的答案来看,Uri.EscapeDataString似乎更可取.但是吗?我做了一些分析以了解差异,这是我想出的:

  • WebUtility.UrlEncode将空间编码为+; Uri.EscapeDataString将其编码为%20.
  • Uri.EscapeDataString百分之-编码!,(,),和*; WebUtility.UrlEncode才不是.
  • WebUtility.UrlEncode百分比编码~; Uri.EscapeDataString才不是.
  • Uri.EscapeDataString抛出UriFormatException超过65,520个字符的字符串; WebUtility.UrlEncode才不是.(比您想象的更常见的问题,特别是在处理URL编码的表单数据时.)
  • Uri.EscapeDataString抛出一个UriFormatException高代理字符 ; WebUtility.UrlEncode才不是.(这是一个UTF-16的东西,可能不太常见.)

对于URL编码目的,字符符合以下三个类别之一:未保留(URL中合法); 保留(合法但具有特殊含义,因此您可能希望对其进行编码); 和其他一切(必须始终编码).

根据RFC,保留字符是::/?#[]@!$&'()*+,;=

并且未保留的字符是字母数字和 -._~

判决

Uri.EscapeDataString明确定义了它的任务:% - 编码所有保留和非法字符.WebUtility.UrlEncode在定义和实现方面都更加模糊.奇怪的是,它编码了一些保留字符而不是其他字符(为什么括号而不是括号?),而且陌生人仍然编码那个无辜无保留的~字符.

因此,我同意流行的建议 - 尽可能使用Uri.EscapeDataString,并了解保留字符/?将被编码.如果您需要处理可能较大的字符串,尤其是URL编码的表单内容,则需要依赖WebUtility.UrlEncode并接受其怪癖,或以其他方式解决问题.


编辑:试图纠正所有上面提到的怪癖Flurl通过Url.Encode,Url.EncodeIllegalCharactersUrl.Decode静态方法.这些是在核心包中(它很小,并不包括所有的HTTP内容),或者可以随意从源代码中删除它们.我欢迎您对这些提出任何意见/反馈.


这是我用来发现哪些字符编码方式不同的代码:

var diffs =
    from i in Enumerable.Range(0, char.MaxValue + 1)
    let c = (char)i
    where !char.IsHighSurrogate(c)
    let diff = new {
        Original = c,
        UrlEncode = WebUtility.UrlEncode(c.ToString()),
        EscapeDataString = Uri.EscapeDataString(c.ToString()),
    }
    where diff.UrlEncode != diff.EscapeDataString
    select diff;

foreach (var diff in diffs)
    Console.WriteLine($"{diff.Original}\t{diff.UrlEncode}\t{diff.EscapeDataString}");
Run Code Online (Sandbox Code Playgroud)

  • 这太棒了! (2认同)
  • 在现代 .net 框架上验证建议的解决方案非常出色。 (2认同)
  • 应该提到的是,**WebUtility** 和 **HttpUtility** 之间存在一些差异。对于十六进制实体,**WebUtility** 使用大写字母,而 **HttpUtility** 使用小写字母。此外,**HttpUtility** 未包含在 .NET Framework“客户端配置文件”的旧子集版本中。**WebUtility** 可从 .NET Framework 4.0 获取。 (2认同)

Joe*_*ler 27

请记住,您可能不应该使用这些方法中的任何一种.微软的反跨站点脚本库包括更换HttpUtility.UrlEncodeHttpUtility.HtmlEncode那都是更符合标准,更安全.作为奖励,您也可以获得一种JavaScriptEncode方法.


CMS*_*CMS 11

Server.UrlEncode()用于向后兼容Classic ASP,

Server.UrlEncode(str);
Run Code Online (Sandbox Code Playgroud)

相当于:

HttpUtility.UrlEncode(str, Response.ContentEncoding);
Run Code Online (Sandbox Code Playgroud)


and*_*eer 5

一样,Server.UrlEncode()来电HttpUtility.UrlEncode()