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它:
-
你有一个简单的URI,像这样:
http://example.org/
Uri.EscapeUriString
不会改变它。 -
您决定手动编辑查询string而不考虑转义:
http://example.org/?key=two words
Uri.EscapeUriString
将(正确)为你逃脱空间:http://example.org/?key=two%20words
-
您决定进一步手动编辑查询string:
http://example.org/?parameter=father&son
但是,这个string不会被
Uri.EscapeUriString
改变,因为它假定和号表示另一个键值对的开始。 这可能是也可能不是你想要的。 -
您决定实际上要将
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中,加号字符表示“空格”。 考虑谷歌询问“快乐的猫”:
这是一个有效的URI(尝试它), EscapeUriString
不会修改它。
现在考虑查询谷歌“快乐的C + +”:
这是一个有效的URI(尝试它),但它会产生一个“幸福的C”的search,因为两个加号被解释为空格。 为了解决这个问题,我们可以将“happy c ++”传递给EscapeDataString
并且:
*)编码的数据串实际上是“happy%20c%2B%2B”; %20是空格字符的hex,%2B是加号字符的hex。
如果您正在使用UriBuilder
,那么您只需要EscapeDataString
可以正确地转义整个URI的一些组件。 @ Livven对这个问题的回答进一步certificate了没有理由使用EscapeUriString
。