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


当前回答

我使用一个加密的字符串作为Url参数(例如http://example.com/Test/myencryptedkey/param2/param3),所以没有c#加密方法可以提供一个安全的Url参数。我最终使用了以下模式:

在加密: Uri.EscapeDataString (myencryptedkey)。取代 ('%', '~');

在解密: Uri.UnescapeDataString (myencryptedkey。取代 ('~', '%'));

注意,在加密期间,替换发生在EscapeDataString()之后,而在解密期间,替换发生在UnescapeDataString()之前;

其他回答

我使用一个加密的字符串作为Url参数(例如http://example.com/Test/myencryptedkey/param2/param3),所以没有c#加密方法可以提供一个安全的Url参数。我最终使用了以下模式:

在加密: Uri.EscapeDataString (myencryptedkey)。取代 ('%', '~');

在解密: Uri.UnescapeDataString (myencryptedkey。取代 ('~', '%'));

注意,在加密期间,替换发生在EscapeDataString()之后,而在解密期间,替换发生在UnescapeDataString()之前;

源代码中的注释清楚地说明了这一差异。为什么这些信息没有通过XML文档注释提出,这对我来说是个谜。

EscapeUriString:

此方法将转义不是保留或的任何字符 无保留字符,包括百分号。请注意, EscapeUriString也不会转义'#'符号。

EscapeDataString:

此方法将转义任何非unreserved字符 字符,包括百分号。

不同之处在于它们如何处理保留字符。EscapeDataString转义它们;EscapeUriString没有。

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

为完整起见,无保留字符为字母数字和-._~

这两种方法都转义既不是保留字符也不是非保留字符。

我不同意认为EscapeUriString是邪恶的一般概念。我认为只转义非法字符(如空格)而不转义保留字符的方法是有用的。但是它在如何处理%字符方面确实有一个怪癖。百分比编码字符(%后面跟着2个十六进制数字)在URI中是合法的。我认为EscapeUriString会更有用,如果它检测到这种模式,并避免编码%时,立即进行2个十六进制数字。

始终使用EscapeDataString(有关原因的更多信息,请参阅下面Livven的答案)

编辑:删除死链接,以了解两者在编码上的差异

一个简单的例子

var data = "example.com/abc?DEF=あいう\x20えお";

Console.WriteLine(Uri.EscapeUriString(data));
Console.WriteLine(Uri.EscapeDataString(data));
Console.WriteLine(System.Net.WebUtility.UrlEncode(data));
Console.WriteLine(System.Web.HttpUtility.UrlEncode(data));

/*
=>
example.com/abc?DEF=%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86%20%E3%81%88%E3%81%8A
example.com%2Fabc%3FDEF%3D%E3%81%82%E3%81%84%E3%81%86+%E3%81%88%E3%81%8A
example.com%2fabc%3fDEF%3d%e3%81%82%e3%81%84%e3%81%86+%e3%81%88%e3%81%8a
*/

加号(+)可以揭示这些方法之间的很多差异。在简单的URI中,加号表示“空格”。考虑查询谷歌中的“happy cat”:

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

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

现在考虑用谷歌查询"happy c++":

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

这是一个有效的URI(尝试一下),但它会产生一个搜索“happy c”的结果,因为两个加号被解释为空格。为了解决这个问题,我们可以将"happy c++"传递给EscapeDataString,瞧*:

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

*)编码后的数据字符串实际上是“happy%20c%2B%2B”;%20是十六进制表示空格字符,%2B是十六进制表示加号字符。

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