简体   繁体   English

Uri.EscapeDataString很奇怪

[英]Uri.EscapeDataString weirdness

Why does EscapeDataString behave differently between .NET 4 and 4.5? 为什么EscapeDataString在.NET 4和4.5之间表现不同? The outputs are 输出是

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

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

The documentation 文档

By default, the EscapeDataString method converts all characters except for RFC 2396 unreserved characters to their hexadecimal representation. 默认情况下,EscapeDataString方法将除RFC 2396非保留字符之外的所有字符转换为十六进制表示形式。 If International Resource Identifiers (IRIs) or Internationalized Domain Name (IDN) parsing is enabled, the EscapeDataString method converts all characters, except for RFC 3986 unreserved characters, to their hexadecimal representation. 如果启用了国际资源标识符(IRI)或国际化域名(IDN)解析,则EscapeDataString方法将除RFC 3986非保留字符之外的所有字符转换为其十六进制表示形式。 All Unicode characters are converted to UTF-8 format before being escaped. 在转义之前,所有Unicode字符都将转换为UTF-8格式。

For reference, unreserved characters are defined as follows in RFC 2396 : 作为参考, RFC 2396中的未保留字符定义如下:

unreserved    = alphanum | mark

mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" |
                (" | ")"

And in RFC 3986 : RFC 3986中

ALPHA / DIGIT / "-" / "." / "_" / "~"

The source code 源代码

It looks like whether each character of EscapeDataString is escaped is determined roughly like this 看起来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

It's at that final check "is an unreserved character" where the choice between RFC2396 and RFC3986 is made. 最后检查“是一个无保留的字符”,在RFC2396和RFC3986之间进行选择。 The source code of the method verbatim is 方法的源代码是逐字的

    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);
    }

And that code refers to 而那段代码指的是

    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;
        }
    }

Confusion 混乱

It seems contradictory that the documentation says the output of EscapeDataString depends on whether IRI/IDN parsing is enabled, whereas the source code says the output is determined by the value of TargetsAtLeast_Desktop_V4_5 . 文档说EscapeDataString的输出取决于是否启用了IRI / IDN解析,而源代码表示输出由TargetsAtLeast_Desktop_V4_5的值确定,这似乎是矛盾的。 Could someone clear this up? 有人可以解决这个问题吗?

A lot of changes has been done in 4.5 comparing to 4.0 in terms of system functions and how it behaves. 在系统功能及其行为方面,4.5与4.0相比已经做了很多改变。 U can have a look at this thread 你可以看一下这个帖子

Why does Uri.EscapeDataString return a different result on my CI server compared to my development machine? 与我的开发机器相比,为什么Uri.EscapeDataString在我的CI服务器上返回不同的结果?

or 要么

U can directly go to the following link 你可以直接转到以下链接

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

All this has been with the input from the users around the world. 所有这一切都来自世界各地用户的意见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM