【问题标题】:Prevent C# from encoding brackets in query string防止 C# 在查询字符串中编码括号
【发布时间】:2010-12-11 21:18:53
【问题描述】:

我需要使用一个接受名为“names[]”的 GET 参数的服务。

例如:GET @987654321@[]=john

当我尝试使用 WebClient 在 C# 中使用它时,括号被编码为 %5B%5D,服务无法理解。当我使用浏览器(未编码)发送上述内容时,一切正常。

这是不起作用的示例:

using (var client = new System.Net.WebClient())
{
    response = client.DownloadString(new Uri("http://example.com/name2id?names[]=john"));
}

由 fiddler 监控,请求如下:

GET http://example.com/name2id?names%5B%5D=john HTTP/1.1
Host: example.com
Connection: Keep-Alive

有什么方法可以让框架不对 URL 进行编码,或者通过其他方式解决这个问题?

附:我不控制 API,因此无法更改。

更新:

这有点奇怪。我找到了一个解决方案,将我的 C# 代码更改为:

using (var client = new System.Net.WebClient())
{
    response = client.DownloadString(new Uri("http://example.com/name2id?names[]=john", true));
}

注意 Uri 中的布尔值 dontEscape。它实际上已被弃用,但它有效吗?谁能解释一下?

【问题讨论】:

  • 我认为唯一的办法是不使用 WebClient 而是使用普通套接字进行手动请求,但即便如此它也不是一个有效的请求,所以我想知道该服务是否会接受的
  • 您可以随时要求提供者在其参数中使用合理的名称,当然还要验证他们确实需要名称中的“[]”。这个要求对我来说似乎很荒谬。
  • 猜猜它已被弃用,因为它允许您创建无效的 URI。但由于您需要一个无效的 URI,我会忽略该警告。

标签: c# http httpwebrequest request


【解决方案1】:

据我了解,RFC2396 [] 不是 URI 中的有效字符。所以在我看来,您的服务需要一个格式错误的 http 请求。

query         = *uric
uric          = reserved | unreserved | escaped
unreserved    = alphanum | mark
mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
reserved      = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
escaped       = "%" hex hex

http://www.ietf.org/rfc/rfc2396.txt

【讨论】:

  • 确实如此,但这是服务所期望的,我无法更改。它确实通过浏览器工作,我实际上找到了一个解决方案。我会更新问题。
  • RFC 3986 (tools.ietf.org/html/rfc3986#section-2.2) 将括号列为保留字符。但是,“保留”表示它们仅有资格进行特殊处理,具体取决于服务器要求。这是 4.5 中 .NET 中所有当前 HTTP 选项的一个主要问题,因为它们都会在某些时候转义 URI。
【解决方案2】:

您确定编码字符是真正的问题吗?

WebClient 类对字符进行了正确编码。如果服务不能处理正确编码的字符,那么服务就会中断。

如果服务以这种方式被破坏,并且无论如何您都必须使用它,那么您必须找到另一种发送请求的方式。

【讨论】:

    【解决方案3】:

    从技术上讲,将[] url 编码为%5B%5D 是正确的,所以问题不在于使用 [],而是提供者没有正确地对路径/查询字符串进行 url 解码

    http://www.albionresearch.com/misc/urlencode.php

    【讨论】:

      【解决方案4】:

      您应该能够将 URI 作为字符串传递

      这样做

       response = client.DownloadString("http://example.com/name2id?names[]=john");
      

      应该在不编码 url 的情况下工作。

      虽然没试过,所以我可能错了。

      【讨论】:

        【解决方案5】:

        正如 CodeInChaos 所述,根据 RFC2396,该 URL 无效。

        为了让C#不转义无效字符,可以使用URI的重载方法:

        new Uri("http://example.com/name2id?names[]=john", true)
        

        但是,这种方法已被弃用,但显然它仍然有效。我不得不忍受弹出的警告:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-01
          • 2011-12-24
          • 1970-01-01
          • 1970-01-01
          • 2011-06-02
          相关资源
          最近更新 更多