System.Net.WebRequest不尊重主机文件

有没有办法让System.Net.WebRequestSystem.Net.WebClient尊重hostslmhosts文件?

例如:在我的hosts文件中,我有:

 10.0.0.1 www.bing.com 

当我尝试在浏览器(IE和FF)中加载Bing时,无法按预期加载。

 Dns.GetHostAddresses("www.bing.com")[0]; // 10.0.0.1 WebRequest.Create("http://10.0.0.1").GetResponse(); // throws exception (expected) WebRequest.Create("http://www.bing.com/").GetResponse(); // unexpectedly succeeds 

同理:

 WebClient wc = new WebClient(); wc.DownloadString("http://www.bing.com"); //succeeds 

为什么System.Net.Dns尊重hosts文件,但System.Net.WebRequest会忽略它? 我需要更改什么才能使WebRequest尊重hosts文件?

附加信息:

  • 如果我禁用IPv6并将我的IPv4 DNS服务器设置为127.0.0.1,则上述代码按预期工作(失败)。 但是,如果我将正常的DNS服务器添加为备用服务器,则会恢复意外行为。
  • 我在3个Win7和2个Vista盒子上重现了这个。 唯一不变的是我公司的网络。
  • 我正在使用.NET 3.5 SP1和VS2008

编辑

根据@Richard Beier的建议,我尝试了System.Net跟踪。 跟踪ON WebRequest失败了。 但是,只要我将跟踪关闭 ,行为就会恢复到意外的成功。 我在调试和发布模式下都在同一台机器上重现了这一点。

编辑2

事实certificate这是公司代理给我们带来的问题。 我们的解决方案是我们的测试机器的自定义代理配置脚本,其中“bing.com”指向DIRECT而不是默认代理。

我认为@Hans Passant在这里发现了这个问题。 看起来你在IE中有一个代理设置。

 Dns.GetHostAddresses("www.bing.com")[0]; // 10.0.0.1 

这是有效的,因为您要求操作系统获取www.bing.com的IP地址

 WebRequest.Create("http://www.bing.com/").GetResponse(); // unexpectedly succeeds 

这是有效的,因为您要求框架从服务器名称获取路径。 该框架使用IE前端使用的相同引擎和设置,因此如果您的公司已经由GPO指定您使用公司代理服务器,则代理服务器会解析www.bing.com而不是您的IP地址。

 WebRequest.Create("http://10.0.0.1").GetResponse(); // throws exception (expected) 

这工作/失败是因为您已要求框架从特定服务器(通过IP)获取网页。 即使您确实有代理集,此代理仍然无法连接到此IP地址。

我希望这个对你有用。

乔纳森

我在Windows 7上使用VS 2010,我无法重现这一点。 我做了相同的hosts文件更改并运行以下代码:

 Console.WriteLine(Dns.GetHostAddresses("www.bing.com")[0]); // 10.0.0.1 var response = WebRequest.Create("http://www.bing.com/").GetResponse(); // * * * Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd()); 

我在标有“* * *”的行上有一个例外。 这是例外细节:

 System.Net.WebException was unhandled Message=Unable to connect to the remote server Source=System StackTrace: at System.Net.HttpWebRequest.GetResponse() at ConsoleApplication2.Program.Main(String[] args) in c:\Data\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 17 InnerException: System.Net.Sockets.SocketException Message=A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 10.0.0.1:80 Source=System ErrorCode=10060 

也许这是早期.NET版本的一个问题,现在已经在.NET 4 / VS 2010中修复了? 您使用的是哪个版本的.NET?

我也从2007年发现了这个post ,其他人遇到了同样的问题。 那里有一些很好的建议,包括以下内容:

  • 打开system.net跟踪

  • 通过使用Dns.GetHostAddresses()将其解析为IP来解决此问题。 然后将IP放入URL中 – 例如“ http://10.0.0.1/ ”。 这可能不是你的选择。

在上面的主题中,mariyaatanasova_msft还说:“HttpWebRequest使用Dns.GetHostEntry来解析主机,因此你可能会得到与Dns.GetHostAddresses不同的结果”。

这个stackoverflow答案有快速和脏的配置来禁用.NET中的代理。 将它放在web.config或app.config中,然后System.Web不会查找底层系统以获取其代理配置。

您应该覆盖默认代理。 HttpWebRequest和WebRequest将设置默认代理(如果存在于Internet Explorer中),并且将绕过您的文件主机

 request.Proxy = new WebProxy(); 

以下只是代码示例:

 try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create("www.bing.com"); request.Proxy = new WebProxy(); request.Method = "POST"; request.AllowAutoRedirect = false; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); if (response.StatusCode == HttpStatusCode.OK) { //some code here } } catch (exception e) { //Some other code here }