Это основано на коде из одного из моих проектов, а также коде, найденном в различных ответах здесь на stackoverflow
.
Сначала нам нужно настроить Cookie aware WebClient
, который будет использовать HTML 1.0
.
public class CookieAwareWebClient : WebClient
{
private CookieContainer cookie = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
request.ProtocolVersion = HttpVersion.Version10;
if (request is HttpWebRequest)
{
(request as HttpWebRequest).CookieContainer = cookie;
}
return request;
}
}
Затем мы устанавливаем код, который обрабатывает Authentication
, и, наконец, загружаем response
.
var client = new CookieAwareWebClient();
client.UseDefaultCredentials = true;
client.BaseAddress = @"http://wallbase.cc";
var loginData = new NameValueCollection();
loginData.Add("usrname", "test");
loginData.Add("pass", "123");
loginData.Add("nopass_email", "Type in your e-mail and press enter");
loginData.Add("nopass", "0");
var result = client.UploadValues(@"http://wallbase.cc/user/login", "POST", loginData);
string response = System.Text.Encoding.UTF8.GetString(result);
Мы можем попробовать это, используя HTML Visualizer
, встроенный в Visual Studio
, оставаясь в режиме отладки, и использовать это, чтобы подтвердить, что мы смогли authenticate
и загрузить домашнюю страницу, оставаясь authenticated
.
Ключом здесь является настройка CookieContainer
и использование HTTP 1.0
вместо 1.1
. Я не совсем уверен, почему принудительное использование 1.0
позволяет успешно проходить проверку подлинности и загружать страницу, но часть решения основана на этом ответе.
https://stackoverflow.com/a/10916014/408182
Я использовал Fiddler , чтобы убедиться, что ответ, отправленный C# Client
, совпадает с ответом моего веб-браузера Chrome
. Это также позволяет мне подтвердить правильность перенаправления C# client
. В этом случае мы можем видеть, что с HTML 1.0
мы получаем HTTP/1.0 302 Found
и затем перенаправляем нас на домашнюю страницу, как и предполагалось. Если мы вернемся к HTML 1.1
, мы получим HTTP/1.1 417 Expectation Failed message
.
В этом потоке stackoverflow имеется некоторая информация об этом сообщении об ошибке.
HTTP POST возвращает ошибку: 417 «Ожидание не выполнено».
Редактировать: Hack / Fix для .NET 3.5
Я потратил много времени, пытаясь выяснить разницу между 3,5 и 4,0, но я серьезно не понимаю. Похоже, что 3.5 создает новый файл cookie после аутентификации, и единственный способ, который я нашел для этого - дважды аутентифицировать пользователя.
Мне также пришлось внести некоторые изменения в WebClient, основываясь на информации из этого поста.
http://dot -net-expertise.blogspot.fr / 2009/10 / cookiecontainer-домен-обработка-ошибка-fix.html
public class CookieAwareWebClient : WebClient
{
public CookieContainer cookies = new CookieContainer();
protected override WebRequest GetWebRequest(Uri address)
{
var request = base.GetWebRequest(address);
var httpRequest = request as HttpWebRequest;
if (httpRequest != null)
{
httpRequest.ProtocolVersion = HttpVersion.Version10;
httpRequest.CookieContainer = cookies;
var table = (Hashtable)cookies.GetType().InvokeMember("m_domainTable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Instance, null, cookies, new object[] { });
var keys = new ArrayList(table.Keys);
foreach (var key in keys)
{
var newKey = (key as string).Substring(1);
table[newKey] = table[key];
}
}
return request;
}
}
var client = new CookieAwareWebClient();
var loginData = new NameValueCollection();
loginData.Add("usrname", "test");
loginData.Add("pass", "123");
loginData.Add("nopass_email", "Type in your e-mail and press enter");
loginData.Add("nopass", "0");
// Hack: Authenticate the user twice!
client.UploadValues(@"http://wallbase.cc/user/login", "POST", loginData);
var result = client.UploadValues(@"http://wallbase.cc/user/login", "POST", loginData);
string response = System.Text.Encoding.UTF8.GetString(result);