【问题标题】:Why doesn't UriBuilder.query escaping (url encoding) the query string?为什么 UriBuilder.query 不转义(url 编码)查询字符串?
【发布时间】:2014-08-25 21:47:07
【问题描述】:

UriBuilder.Query 属性“包含 URI 中包含的任何查询信息。” According to the docs, "查询信息根据 RFC 2396 进行转义。"

基于此,并且由于此属性是可写的,我假设当您设置它时,System.UriBuilder 将解析您的查询字符串,并根据 RFC 2396 进行转义(url 编码)。特别是 { 和 } 是不在未保留的字符集中,所以they should be escaped according to page 9 of RFC 2396。但是,System.UriBuilder 似乎没有进行任何转义。

我需要手动 Server.URLEncode 参数,还是有办法让System.UriBuilder 处理编码?

这是我的示例代码。你可以run this on ideone.com and see that, indeed, nothing is URL encoded

using System;

public class Test
{
    public static void Main()
    {
        var baseUrl = new System.Uri("http://www.bing.com");
        var builder = new System.UriBuilder(baseUrl);
        string name = "param";
        string val = "{'blah'}";
        builder.Query = name + "=" + val;
        
        // Try several different ouput methods; none will be URL encoded
        Console.WriteLine(builder.ToString());
        Console.WriteLine(builder.Uri.ToString());
        Console.WriteLine(builder.Query);
    }
}

【问题讨论】:

  • 我看不到任何可以执行任何类型转换的明显代码。我想知道文档是否措辞非常糟糕,应该说该值应该根据 RFC2396 进行转义。
  • 是的,好吧,当文档说查询被转义时,它们意味着 Uri 对象的 Query 属性在读取时包含转义数据。如果您自己设置此数据,则必须首先为其提供转义数据。如果它为您转义了数据,那将导致极易出错的+= 工作流。
  • @Damien_The_Unbeliever,我想知道文档中的“查询信息被转义”是否应该是“查询信息应该被转义”,或者更清楚地说,“你应该在写作之前转义查询信息它到这个属性。”

标签: c# .net


【解决方案1】:
builder.Uri.AbsoluteUri

是您正在寻找的机器人,在您的情况下,它会返回

http://www.bing.com/?param=%7B'blah'%7D

考虑到很难知道&+= 符号是否应该被编码,当你分配给.Query 属性时,最好自己进行转义。

【讨论】:

  • 我尝试了 AbsoluteUri,它似乎给出了相同的未编码输出...请参阅此 ideone.com 测试:ideone.com/Xl7qfp
  • @Josh :如果您在控制台应用程序中执行此操作,则可以正确转义。 IDEone 正在对控制台输出做一些时髦的事情。
  • 虽然这不能回答我的确切问题(“为什么 UriBuilder 不逃避 Query 属性?”),但它确实给了我真正想要的答案。谢谢!只是为了完整起见,我添加了一个答案,直接回答了我提出的确切问题。
  • 我想知道为什么?标记在我的代码中被转义。这给出了答案。谢谢!我终于用这种方式替换了 UriBuilder stackoverflow.com/questions/372865/path-combine-for-urls/…
【解决方案2】:

在实践中,我发现您需要自己手动转义查询参数。 System.Uri.AbsoluteUri 将尝试为您逃避事情(如spender's answer 中所述),但它可能不会成功。例如,给定值someemail+test@gmail.com,AbsoluteUri 将不转义+,而应将其转义为%2B。否则,当查询字符串被解码时,+会被转换成空格,留下someemail test@gmail.com作为最终解码的值。

最重要的是,您需要自己转义它以确保它被正确转义。

在使用 dotPeek 查看 UriBuilder.Query 获取/设置代码中的代码后,我不得不得出结论,文档只是写得不好。而不是“查询信息根据 RFC 2396 转义”,而应该说“查询信息应该根据 RFC 2396 转义。”

从下面System.UriBuilder.Query 的dotPeek 反编译可以看出,查询getter 或setter 中没有发生自动转义。

[__DynamicallyInvokable]
public string Query
{
  [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get
  {
    return this.m_query;
  }
  [__DynamicallyInvokable] set
  {
    if (value == null)
      value = string.Empty;
    if (value.Length > 0)
      value = (string) (object) '?' + (object) value;
    this.m_query = value;
    this.m_changed = true;
  }
}

System.Uri.AbsoluteUri,然而,试图逃避事情。注意 getter 中对 this.GetParts 的调用:

[__DynamicallyInvokable]
public string Authority
{
  [__DynamicallyInvokable] get
  {
    if (this.IsNotAbsoluteUri)
      throw new InvalidOperationException(System.SR.GetString("net_uri_NotAbsolute"));
    else
      return this.GetParts(UriComponents.Host | UriComponents.Port, UriFormat.UriEscaped);
  }
}

【讨论】:

  • 是的 UrlBuilder 有点欠缺...您现在可以看到 source 并且这里有一个带有 += here 的错误
猜你喜欢
  • 1970-01-01
  • 2011-07-01
  • 2011-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多