【问题标题】:Literal ampersands in System.Uri query stringSystem.Uri 查询字符串中的文字和符号
【发布时间】:2010-05-20 09:22:31
【问题描述】:

我正在开发一个客户端应用程序,该应用程序使用 restful 服务按名称查找公司。 能够在查询中包含文字和符号很重要,因为这个字符在公司名称中很常见。

但是,每当我将 %26(URI 转义的 & 字符)传递给 System.Uri 时,它都会将其转换回常规 & 字符!仔细观察,唯一没有被转换回来的两个字符是哈希 (%23) 和百分比 (%25)。

假设我想搜索一家名为“Pierce & Pierce”的公司:

var endPoint = "http://localhost/companies?where=Name eq '{0}'";
var name = "Pierce & Pierce";
Console.WriteLine(new Uri(string.Format(endPoint, name)));
Console.WriteLine(new Uri(string.Format(endPoint, name.Replace("&", "%26"))));
Console.WriteLine(new Uri(string.Format(endPoint, Uri.EscapeUriString(name))));
Console.WriteLine(new Uri(string.Format(endPoint, Uri.EscapeDataString(name))));

以上四种组合均返回:

http://localhost/companies?where=Name eq 'Pierce & Pierce'

这会导致服务器端出现错误,因为 & 号被(正确地)解释为查询 arg 分隔符。我真正需要它返回的是原始字符串:

http://localhost/companies?where=Name eq 'Pierce %26 Pierce'

如何在不完全丢弃 System.Uri 的情况下解决此问题? 我不能在最后一刻用 %26 替换所有与号,因为通常会涉及多个查询参数,我不想破坏它们的分隔符。

注意:this question 中讨论了类似的问题,但我特指System.Uri

【问题讨论】:

    标签: .net escaping uri query-string


    【解决方案1】:

    不只是 URL 中的 & 符号不正确。有效的 URL 不能包含空格。

    EscapeDataString 方法可以很好地正确编码字符串,您应该对整个值进行编码,而不仅仅是名称:

    Uri.EscapeDataString("Name eq 'Pierce & Pierce'")
    

    结果:

    Name%20eq%20'Pierce%20%26%20Pierce'
    

    当您使用此字符串创建Uri 时,它将是正确的。要查看 URL,您可以使用 AbsoluteUri 属性。如果您只是将Uri 转换为字符串(调用ToString 方法),则URL 将不转义,因此看起来不正确。

    【讨论】:

    • 啊,现在我明白了。 ToString() 是 uri 的非转义人类可读版本。
    【解决方案2】:

    我遇到了同样的问题。虽然查询字符串使用 Uri.EscapeDataString 进行了转义,并且 AbsoluteUri 属性确实正确地表示了它,但是 WebBrowser 以非转义格式发送 Uri。

      currentUri = new System.Uri(ServerAgent.urlBase + "/MailRender?uid="
    + Uri.EscapeDataString(uid);
    

    webBrowser.Navigate(currentUri);

    加号('+')转换为%2B,但服务器仍然在URL中得到+,然后通过HttpServeletRequest.getParameter()调用转换为空格('')

    【讨论】:

      【解决方案3】:

      我通过创建 Uri 的派生类解决了这个问题

          class Uri2 : System.Uri
      {
          public Uri2(string url) : base(url)
          {
          }
      
          public override string ToString()
          {
              return AbsoluteUri;
          }
      }
      

      在任何使用 System.Uri 的地方,都用 Uri2 代替。 我不知道这是否是 .NetCF 的错误,WebBrowser 应该以编码格式发送 URL,即 AbsoluteUri 的值,而不是来自 ToString() 的值

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-12-21
        • 2010-10-06
        • 1970-01-01
        • 2019-02-23
        • 2010-11-20
        • 2012-11-18
        • 1970-01-01
        • 2017-06-10
        相关资源
        最近更新 更多