Necromancing.
Для тех, кто все еще на .NET 2.0
Это на самом деле довольно легко, если вы знаете, как.
Проблема в том, что вы не можете установить заголовок хоста, потому что среда не позволит вам изменить значение во время выполнения. (.net Framework 4.0+ позволит вам переопределить хост в httpwebrequest).
Следующая попытка будет установить заголовок с отражением - как показано в ответе с верхним голосом здесь - чтобы обойти его, что позволит вам изменить значение заголовка. Но во время выполнения он перезапишет это значение с хост-частью URL , что означает, что рефлексия вам ничего не принесет, поэтому я не понять, почему люди продолжают голосовать за это.
Если dns-name не существует, что, честно говоря, является единственным случаем, когда вы хотите сделать это в первую очередь, вы не можете установить его, потому что .NET не может его разрешить, и вы не может переопределить .NET DNS resolver.
Но вы можете настроить веб-прокси с тем же IP-адресом, что и у сервера назначения.
Итак, если ваш сервер IP-адрес 28.14.88.71:
public class myweb : System.Net.WebClient
{
protected override System.Net.WebRequest GetWebRequest(System.Uri address)
{
System.Net.WebRequest request = (System.Net.WebRequest)base.GetWebRequest(address);
//string host = "redmine.nonexistantdomain.com";
//request.Headers.GetType().InvokeMember("ChangeInternal",
// System.Reflection.BindingFlags.NonPublic |
// System.Reflection.BindingFlags.Instance |
// System.Reflection.BindingFlags.InvokeMethod, null,
// request.Headers, new object[] { "Host", host }
//);
//server IP and port
request.Proxy = new System.Net.WebProxy("http://28.14.88.71:80");
// .NET 4.0 only
System.Net.HttpWebRequest foo = (System.Net.HttpWebRequest)request;
//foo.Host = host;
// The below reflection-based operation is not necessary,
// if the server speaks HTTP 1.1 correctly
// and the firewall doesn't interfere
// https://yoursunny.com/t/2009/HttpWebRequest-IP/
System.Reflection.FieldInfo horribleProxyServicePoint = (typeof(System.Net.ServicePoint))
.GetField("m_ProxyServicePoint", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
horribleProxyServicePoint.SetValue(foo.ServicePoint, false);
return foo; // or return request; if you don't neet this
}
}
и вуаля, теперь
myweb wc = new myweb();
string str = wc.DownloadString("http://redmine.netexistantdomain.com");
и вы получите правильную страницу назад, если 28.14.88.71 является веб-сервером с виртуальным хостингом на основе имен (на основе http-host-header).
Теперь у вас есть правильный ответ на исходный вопрос как для WebRequest, так и для WebClient. Я думаю, что использование пользовательских сокетов для этого было бы неправильным подходом, особенно когда нужно использовать SSL и когда такое простое реальное решение ...