EscapeUriString和EscapeDataString有什么区别?

如果只处理url编码,我应该使用EscapeUriString ?

如果您正在转义的是URI,并且EscapeDataString在其他地方,则使用EscapeUriString

这两个string如何编码存在差异。

更多信息: http : //blogs.msdn.com/b/yangxind/archive/2006/11/09/don-t-use-net-system-uri-unescapedatastring-in-url-decoding.aspx

我没有发现现有的答案令人满意,所以我决定深入一点,以解决这个问题。 令人惊讶的是,答案非常简单:

没有任何理由使用Uri.EscapeUriString 如果您需要百分比编码string,请始终使用Uri.EscapeDataString

为什么是这样? 根据文件 :

使用EscapeUriString方法准备未转义的URIstring作为Uri构造函数的参数。

这真的没有道理。 根据RFC 2396 :

一个URI总是处于“转义”的forms,因为转义或撤销已完成的URI可能会改变它的语义。

虽然引用的RFC已被RFC 3986废弃, 但这一点仍然存在。 我们来看看一些具体的例子来validation它:

  1. 你有一个简单的URI,像这样:

     http://example.org/ 

    Uri.EscapeUriString不会改变它。

  2. 您决定手动编辑查询string而不考虑转义:

     http://example.org/?key=two words 

    Uri.EscapeUriString将(正确)为你逃脱空间:

     http://example.org/?key=two%20words 
  3. 您决定进一步手动编辑查询string:

     http://example.org/?parameter=father&son 

    但是,这个string不会被Uri.EscapeUriString改变,因为它假定和号表示另一个键值对的开始。 这可能是也可能不是你想要的。

  4. 您决定实际上要将key参数设置为father&son ,因此您通过转义符&手动修复了以前的URL:

     http://example.org/?parameter=father%26son 

    但是, Uri.EscapeUriString也会Uri.EscapeUriString百分号,导致双重编码:

     http://example.org/?parameter=father%2526son 

正如你所看到的,使用Uri.EscapeUriString来达到预期的目的,使得不可能在查询string中使用&作为键或值的一部分,而不是作为多个键 – 值对之间的分隔符。

这是因为,如果误导了整个URI的转义,它会忽略保留的字符,只能转义既不被保留也不被保留的字符,这与文档相反。 这样你就不会像http%3A%2F%2Fexample.org%2F那样结束了,但是你最终会遇到上述的问题。


最后,如果你的URI是有效的,它不需要被转义作为parameter passing给Uri构造器,如果它不合法,那么调用Uri.EscapeUriString是一个神奇的解决scheme。 实际上,如果不是大多数情况下,它会起作用,但绝不是可靠的。

您应该始终通过收集键值对和百分比编码来构build您的URL和查询string,然后将它们与必要的分隔符连接起来。 您可以使用Uri.EscapeDataString来达到这个目的,但是不能使用Uri.EscapeUriString ,因为它不会像上面提到的那样转义保留字符。

加(+)字符可以揭示这些方法之间的区别。 在一个简单的URI中,加号字符表示“空格”。 考虑谷歌询问“快乐的猫”:

https://www.google.com/?q=happy+cat

这是一个有效的URI(尝试它), EscapeUriString不会修改它。

现在考虑查询谷歌“快乐的C + +”:

https://www.google.com/?q=happy+c++

这是一个有效的URI(尝试它),但它会产生一个“幸福的C”的search,因为两个加号被解释为空格。 为了解决这个问题,我们可以将“happy c ++”传递给EscapeDataString并且:

https://www.google.com/?q=happy+c%2B%2B

*)编码的数据串实际上是“happy%20c%2B%2B”; %20是空格字符的hex,%2B是加号字符的hex。

如果您正在使用UriBuilder ,那么您只需要EscapeDataString可以正确地转义整个URI的一些组件。 @ Livven对这个问题的回答进一步certificate了没有理由使用EscapeUriString