如何获得Uri.EscapeDataString遵守RFC 3986如何获得、Uri、EscapeDataString、RFC

2023-09-02 01:54:42 作者:荒废之徒

Uri类默认为RFC 2396对于OpenID和OAuth的,我需要的URI转义符合RFC 3986.

The Uri class defaults to RFC 2396. For OpenID and OAuth, I need Uri escaping consistent with RFC 3986.

从的System.Uri类文档:

在默认情况下,在URI中的任何保留字符转义按照RFC 2396这种行为的变化,如果国际资源标识符或国际域名解析可用在URI中的情况下,保留字符转义按照RFC 3986和RFC 3987。

By default, any reserved characters in the URI are escaped in accordance with RFC 2396. This behavior changes if International Resource Identifiers or International Domain Name parsing is enabled in which case reserved characters in the URI are escaped in accordance with RFC 3986 and RFC 3987.

该文件还指出,激活此IRI模式,因此RFC 3986行为意味着增加一个URI部分元素的Machine.config,这为您的应用程序/ web.config文件:

The documentation also states that activating this IRI mode and thus the RFC 3986 behavior means adding a uri section element to machine.config and this to your app/web.config file:

<configuration>
  <uri>
  <idn enabled="All" />
  <iriParsing enabled="true" />
  </uri>
</configuration>

不过,这是否是present在config文件还是不行,我得到了相同的(非3986)逃逸行为的.NET 3.5 SP1的应用程序。 还有什么,我需要做的就是 Uri.EscapeDataString 使用RFC 3986规定?(具体而言,为在规定逃避保留字符该RFC)

But whether this is present in the .config file or not, I'm getting the same (non-3986) escaping behavior for a .NET 3.5 SP1 app. What else do I need to do to get Uri.EscapeDataString to use the RFC 3986 rules? (specifically, to escape the reserved characters as defined in that RFC)

推荐答案

已经不能够得到Uri.EscapeDataString承担RFC 3986的行为,我写我自己RFC 3986标准的逃逸方法。它利用Uri.EscapeDataString,然后'升级'的逃逸到RFC 3986合规性。

Having not been able to get Uri.EscapeDataString to take on RFC 3986 behavior, I wrote my own RFC 3986 compliant escaping method. It leverages Uri.EscapeDataString, and then 'upgrades' the escaping to RFC 3986 compliance.

/// <summary>
/// The set of characters that are unreserved in RFC 2396 but are NOT unreserved in RFC 3986.
/// </summary>
private static readonly string[] UriRfc3986CharsToEscape = new[] { "!", "*", "'", "(", ")" };

/// <summary>
/// Escapes a string according to the URI data string rules given in RFC 3986.
/// </summary>
/// <param name="value">The value to escape.</param>
/// <returns>The escaped value.</returns>
/// <remarks>
/// The <see cref="Uri.EscapeDataString"/> method is <i>supposed</i> to take on
/// RFC 3986 behavior if certain elements are present in a .config file.  Even if this
/// actually worked (which in my experiments it <i>doesn't</i>), we can't rely on every
/// host actually having this configuration element present.
/// </remarks>
internal static string EscapeUriDataStringRfc3986(string value) {
    // Start with RFC 2396 escaping by calling the .NET method to do the work.
    // This MAY sometimes exhibit RFC 3986 behavior (according to the documentation).
    // If it does, the escaping we do that follows it will be a no-op since the
    // characters we search for to replace can't possibly exist in the string.
    StringBuilder escaped = new StringBuilder(Uri.EscapeDataString(value));

    // Upgrade the escaping to RFC 3986, if necessary.
    for (int i = 0; i < UriRfc3986CharsToEscape.Length; i++) {
    	escaped.Replace(UriRfc3986CharsToEscape[i], Uri.HexEscape(UriRfc3986CharsToEscape[i][0]));
    }

    // Return the fully-RFC3986-escaped string.
    return escaped.ToString();
}
 
精彩推荐
图片推荐