我看过很多帖子询问有关使用不符合规范的 Uris 的问题,但没有一个有很好的答案。我正在编写 Windows Phone 控件,它需要使用 HTTP GET 请求 ATOM 数据。 URL 需要在其中包含字符 %3d(等号)。这是不可协商的,因为它是我无法控制的第三方服务。想象一个如下所示的 URL:
http://host.com?arg1=val1&arg=val2%3d
我将 WebClient 与 DownloadStringAsync 结合使用,但它只接受 Uri 对象,不接受字符串中的 URL。 Uri 对象自动取消转义这些字符并发送:
http://host.com?arg1=val1&arg=val2=
这失败了。有一个已弃用的构造函数参数“UserExcaped”正是我所需要的,但它不可用。我担心我唯一的选择是使用原始套接字和最少的 HTTP 支持实现我自己的字符串下载方法。
还有其他想法吗?非常感谢您的帮助!!
更新
<code>
string apps = "http://blah.com/api?prev=AAAAAAA%3d&next=BBBBBBB";
var u = new Uri(apps);
string apps2 = u.ToString();
Debug.Assert(apps == apps2); // That %3d will always be converted to an equals sign</code>
我还应该指出,如果我试图通过将百分比编码为 %25(因此它是“prev=AAAAAA%253d&next=BBBBB”)来变得聪明,那么我会得到 %25 仍然完好无损的确切文字字符串!它只是 %3d 积极地转换为等号。
最佳答案
Uri
类就是这样设计的。 MSDN :
As part of canonicalization in the constructor for some schemes, escaped representations are compacted. The schemes for which URI will compact escaped sequences include the following: file, http, https, net.pipe, and net.tcp. For all other schemes, escaped sequences are not compacted.
您是否尝试过使用 HttpWebRequest?它比 WebClient 稍微多一些工作,但它允许您传递一个字符串作为目标。
编辑 - 另一种方法可能是创建您自己的允许编码版本的 UriParser
。扩展 UriParser
的示例可以是 found here .
对于其他不运行Windows Phone 的人,您可以使用反射
来解决这个问题。
MethodInfo getSyntax = typeof(UriParser).GetMethod("GetSyntax", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
FieldInfo flagsField = typeof(UriParser).GetField("m_Flags", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
if (getSyntax != null && flagsField != null)
{
foreach (string scheme in new[] { "http", "https" })
{
UriParser parser = (UriParser)getSyntax.Invoke(null, new object[] { scheme });
if (parser != null)
{
int flagsValue = (int)flagsField.GetValue(parser);
//0x20000 is the SimpleUserSyntax attribute
if ((flagsValue & 0x20000) != 0)
flagsField.SetValue(parser, flagsValue & ~0x20000);
}
}
}
Uri u = new Uri("http://host.com?arg1=val&arg=val2%3d");
//At this point, the %3d remains as expected.
关于c# - 文字 Uri 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8855866/