以这个例子为例:
var client = new HttpClient();
await client.GetAsync("http://www.google.com?q=%2D");
这实际上将请求发送到“ Aggregate Report”。我不想.NET更改我的网址。
此行为来自System.Uri,它似乎无法转义这些字符。
如何防止Uri / HttpClient更改我的网址?
.NET Framework 4.7.2
更新:此行为是设计使然。我仍然不敢相信没有办法解决这个问题。如果我实际上想向google.com发送“?q =%2D是什么意思”怎么办?现在,将其发送为“ http://www.google.com?q=-”。这不是我的本意。
答案 0 :(得分:1)
基于反射的可能局部解决方案。
我认为问题是-
被列为特殊字符,在这里:https://referencesource.microsoft.com/#System/net/System/UriHelper.cs,657。我认为没有办法修改http
方案来改变这种行为。
以前存在一个错误,此错误已得到修复,该错误与Uri
解析文件路径有关。当时,解决方法是使用反射来更改相关UriParser
的专用标志:https://stackoverflow.com/a/2285321/1462295
这是一个快速演示,您必须评估它是否有帮助。这取决于是调用uri.ToString()
(然后可能会有所帮助)还是uri.GetComponents
(然后您必须弄清楚其他事情)。这段代码到达Uri
对象中,并将解析后的字符串替换为其他内容。这是代码和控制台输出:
static void Main(string[] args)
{
var surl = "http://www.google.com?q=%2D";
var url = new Uri(surl);
Console.WriteLine("Broken: " + url.ToString());
// Declared in Uri class as
// private UriInfo m_Info;
// https://referencesource.microsoft.com/#System/net/System/URI.cs,129
FieldInfo infoField = url.GetType().GetField("m_Info", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
// Immediately after m_Info is declared, the private class definition is given:
// private class UriInfo {
// public string String;
// ...
// };
object info = infoField.GetValue(url);
FieldInfo infoStringField = info.GetType().GetField("String");
// If you check the value of m_Info.String, you'll see it has the
// modified string with '?q=-'.
// The idea with this block of code is to replace the parsed
// string with the one that you want.
// This just replaces the string with the original value.
infoStringField.SetValue(info, surl);
// ToString() @ https://referencesource.microsoft.com/#System/net/System/URI.cs,1661
// There are a couple of 'if' branches, but the last line is
// return m_Info.String;
// This is the idea behind the above code.
Console.WriteLine("Fixed: " + url.ToString());
// However, GetComponents uses entirely different logic:
Console.WriteLine($"Still broken: {url.GetComponents(UriComponents.AbsoluteUri, UriFormat.Unescaped)}");
Console.WriteLine($"Still broken: {url.GetComponents(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped)}");
Console.WriteLine($"Still broken: {url.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped)}");
Console.WriteLine("Press ENTER to exit ...");
Console.ReadLine();
}
控制台输出:
Broken: http://www.google.com/?q=-
Fixed: http://www.google.com?q=%2D
Still broken: http://www.google.com/?q=-
Still broken: http://www.google.com/?q=-
Still broken: http://www.google.com/?q=-
Press ENTER to exit ...
您可能会从代码here中找到其他启发,该代码确实使用了反射,但是也定义了自己的使用方案。请注意提到的信任问题。
您提到了.Net Framework 4.7.2,它应与上述代码一起使用。 dotnet核心不会。