Uri.EscapeDataString很奇怪

Tre*_*eld 6 .net c# escaping percent-encoding .net-4.5

为什么EscapeDataString在.NET 4和4.5之间表现不同?输出是

  • Uri.EscapeDataString("-_.!~*'()") => "-_.!~*'()"

  • Uri.EscapeDataString("-_.!~*'()") => "-_.%21~%2A%27%28%29"

文档

默认情况下,EscapeDataString方法将除RFC 2396非保留字符之外的所有字符转换为十六进制表示形式.如果启用了国际资源标识符(IRI)或国际化域名(IDN)解析,则EscapeDataString方法将除RFC 3986非保留字符之外的所有字符转换为其十六进制表示形式.在转义之前,所有Unicode字符都将转换为UTF-8格式.

作为参考,RFC 2396中的未保留字符定义如下:

unreserved    = alphanum | mark

mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" |
                (" | ")"
Run Code Online (Sandbox Code Playgroud)

RFC 3986中:

ALPHA / DIGIT / "-" / "." / "_" / "~"
Run Code Online (Sandbox Code Playgroud)

源代码

看起来EscapeDataString的每个字符是否被转义都是大致相同的

is unicode above \x7F
  ? PERCENT ENCODE
  : is a percent symbol
    ? is an escape char
      ? LEAVE ALONE
      : PERCENT ENCODE
    : is a forced character
      ? PERCENT ENCODE
      : is an unreserved character
        ? PERCENT ENCODE
Run Code Online (Sandbox Code Playgroud)

最后检查"是一个无保留的字符",在RFC2396和RFC3986之间进行选择.方法的源代码是逐字的

    internal static unsafe bool IsUnreserved(char c)
    {
        if (Uri.IsAsciiLetterOrDigit(c))
        {
            return true;
        }
        if (UriParser.ShouldUseLegacyV2Quirks)
        {
            return (RFC2396UnreservedMarks.IndexOf(c) >= 0);
        }
        return (RFC3986UnreservedMarks.IndexOf(c) >= 0);
    }
Run Code Online (Sandbox Code Playgroud)

而那段代码指的是

    private static readonly UriQuirksVersion s_QuirksVersion = 
        (BinaryCompatibility.TargetsAtLeast_Desktop_V4_5
             // || BinaryCompatibility.TargetsAtLeast_Silverlight_V6
             // || BinaryCompatibility.TargetsAtLeast_Phone_V8_0
             ) ? UriQuirksVersion.V3 : UriQuirksVersion.V2;

    internal static bool ShouldUseLegacyV2Quirks {
        get {
            return s_QuirksVersion <= UriQuirksVersion.V2;
        }
    }
Run Code Online (Sandbox Code Playgroud)

混乱

文档说EscapeDataString的输出取决于是否启用了IRI/IDN解析,而源代码表示输出由值决定,这似乎是矛盾的TargetsAtLeast_Desktop_V4_5.有人可以解决这个问题吗?

小智 -1

与 4.0 相比,4.5 在系统功能和行为方式方面进行了很多更改。你可以看看这个帖子

与开发计算机相比,为什么 Uri.EscapeDataString 在我的 CI 服务器上返回不同的结果?

或者

你可以直接进入以下链接

http://msdn.microsoft.com/en-us/library/hh367887(v=vs.110).aspx

所有这一切都来自世界各地用户的输入。