9

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

例如:在我的主机文件中,我有:

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尊重主机文件但System.Net.WebRequest忽略它?我需要更改什么才能使 WebRequest 尊重主机文件?

附加信息:

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

编辑

根据@Richard Beier 的建议,我尝试了System.Net追踪。随着跟踪失败WebRequest,它应该。但是,一旦我关闭跟踪行为就会恢复到意外的成功。我已经在调试和发布模式下在与以前相同的机器上复制了它。

编辑 2

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

4

3 回答 3

7

我认为@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 地址。

我希望这个对你有用。

乔纳森

于 2010-08-14T11:38:08.087 回答
3

我在 Windows 7 上使用 VS 2010,但无法重现。我进行了相同的主机文件更改并运行了以下代码:

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 年的这个帖子,其他人也遇到了同样的问题。那里有一些很好的建议,包括以下内容:

  • 打开system.net 跟踪

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

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

于 2010-08-14T07:15:13.040 回答
0

您应该覆盖默认代理。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
}
于 2016-03-18T17:13:56.793 回答