2010-05-30 2 views
3

Я пытаюсь программно отправить POST-запрос на веб-сервер, чтобы войти в систему, а затем выполнить другие запросы, требующие входа.HttpWebRequest ответ производит HTTP 422. Почему?

Это мой код:

byte[] data = Encoding.UTF8.GetBytes(
    String.Format(
     "login={0}&password={1}&authenticity_token={2}" 
     +"&login_submit=Entra&remember_me=1", 
     HttpUtility.UrlEncode(username), HttpUtility.UrlEncode(password), 
     HttpUtility.UrlEncode(token))); 

    //Create HTTP-request for login 
    HttpWebRequest request = 
      (HttpWebRequest)HttpWebRequest.Create("http://www.xxx.xx/xx/xx"); 

    request.Method = "POST"; 
    request.ContentType = "application/x-www-form-urlencoded"; 
    request.ContentLength = data.Length; 
    request.CookieContainer = new CookieContainer(); 

    request.Accept = "application/xml,application/xhtml+xml,text/html; 
        +"q=0.9,text/plain ;q=0.8,image/png,*/*;q=0.5"; 
    request.Referer = "http://www.garzantilinguistica.it/it/session"; 
    request.Headers.Add("Accept-Language", "de-DE"); 
    request.Headers.Add("Origin", "http://www.xxx.xx"); 
    request.UserAgent = "C#"; 
    request.Headers.Add("Accept-Encoding", "gzip, deflate"); 

После отправки запроса

//Send post request 
    var requestStream = request.GetRequestStream(); 

    requestStream.Write(data, 0, data.Length); 
    requestStream.Flush(); 
    requestStream.Close(); 

... Я хочу, чтобы получить ответ сервера:

//Get Response 
    StreamReader responseStreamReader = new 
    StreamReader(
     request.GetResponse().GetResponseStream()); //WebException: HTTP 422! 
    string content = responseStreamReader.ReadToEnd(); 

Этот кусок кода пожаров WebException, который сообщает мне, что сервер ответил HTTP 422 (необработанный объект из-за семантической ошибки s)

Затем я сравнил (используя TCP/IP снифферы) запросы моей программы и браузера (который, конечно же, создает действительный POST-запрос и получает правильный ответ).

(1) запрос моей программы:

POST /it/session HTTP/1.1 
Content-Type: application/x-www-form-urlencoded 
Accept: application/xml,application/xhtml+xml,text/html; 
q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 
Referer: http://www.garzantilinguistica.it/it/session 
Accept-Language: de-DE 
Origin: http://www.garzantilinguistica.it 
User-Agent: Test 
Accept-Encoding: gzip, deflate 
Host: www.garzantilinguistica.it 
Content-Length: 148 
Expect: 100-continue 
Connection: Keep-Alive 


HTTP/1.1 100 Continue 


login=thespider14%40hotmail.com&password=xxxxx&authenticity_token=4vLgtwP3nFNg4NeuG4MbUnU7sy4z91Wi8WJXH0POFmg%3d&login_submit=Entra&remember_me=1 

(2) запрос браузера:

POST /it/session HTTP/1.1 
    Host: www.garzantilinguistica.it 
    Referer: http://www.garzantilinguistica.it/it/session 
    Accept: application/xml,application/xhtml+xml,text/html;q=0.9, 
text/plain;q=0.8,image/png,*/*;q=0.5 
    Accept-Language: de-DE 
    Origin: http://www.garzantilinguistica.it 
    User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de-DE) AppleWebKit/531.22.7 (KHTML, like Gecko) Version/4.0.5 Safari/531.22.7 
    Accept-Encoding: gzip, deflate 
    Content-Type: application/x-www-form-urlencoded 
    Cookie: __utma=244184339.652523587.1275208707.1275208707.1275211298.2; __utmb=244184339.20.10.1275211298; __utmc=244184339; __utmz=244184339.1275208707.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); _garzanti2009_session=BAh7CDoPc2Vzc2lvbl9pZCIlZDg4MWZjNjg2YTRhZWE0NDQ0ZTJmMTU2YWY4ZTQ1NGU6EF9jc3JmX3Rva2VuIjFqRWdLdll3dTYwOTVVTEpNZkt6dG9jUCtaZ0o4V0FnV2V5ZnpuREx6QUlZPSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNoSGFzaHsGOgplcnJvciIVbG9naW4gbm9uIHZhbGlkbwY6CkB1c2VkewY7CFQ%3D--4200fa769898dd156faa49e457baf660cf068d08 
    Content-Length: 144 
    Connection: keep-alive 

authenticity_token=jEgKvYwu6095ULJMfKztocP%2BZgJ8WAgWeyfznDLzAIY%3D&login=thespider14%40hotmail.com&password=xxxxxx&remember_me=1&commit=Entra 
HTTP/1.1 302 Found 

Может кто-то поможет понять, какая часть запроса мне не хватает или что главный разница между браузером и моим запросом? Почему я получаю это 422?

EDIT:

Я заметил, что мой запрос содержит заголовок Expect со значением 100-продолжением, в то время как браузер не делает. Я установил request.Expect -property на null и до "". Но я просто не мог избавиться от него. Какие-либо предложения? Может ли это быть корнем всего зла?

EDIT:

Наконец я удалил Expect -header. Но это не помогло. Есть идеи? я активировал CookieContainer установки

request.CookieContainer = new CookieContainer(); 

Но я не могу видеть Cookie-заголовок в HTTP-следе. Зачем?

+0

Если первая трассировка HTTP верна (не является жертвой форматирования в этом сообщении), я не могу видеть тело HTTP, которое вы отправляете. «Content-Length» установлен в 111, но я вижу только «http/1.1 100 Continue», который был бы ответом, я пропускаю контент «данных». Во второй трассировке HTTP я вижу только «authentication_token», а в вашем коде вы используете 3 переменные. Код 422 указывает на «неправильное экранирование содержимого тела». Вероятно, он пытается прочитать одну из переменных как сущности. Любой шанс, что у вас есть ';' символ не экранирован в строках? –

+0

Я просто избежал строк, содержащихся в моих переменных, используя HttpUtility.UrlEncode(). Но до сих пор нет успеха. – Simon

ответ

4

Хорошо, у меня есть ребята.

У меня было две проблемы.

  1. HTTP 1.1/100 продолжают

    Я решил, установив

  2. Сервер, repsonded с 422 из-за проблем, связанных с печенья. Запрос POST должен передать контейнер cookie, который содержит файл cookie с текущим идентификатором сессии. Если этот идентификатор сеанса не передан, сервер будет ответить 422. Для того чтобы иметь файл cookie с идентификатором сеанса, мне пришлось выполнить простой HTTP-запрос на странице входа. Этот запрос возвратил контейнер cookie с необходимым идентификатором сеанса. Затем я передал возвращаемый контейнер cookie в запрос POST.

    //cookie container of previous request 
    postRequest.CookieContainer = cookieContainer; 
    

При этом настройка запрос POST может быть успешно отправлен.

Благодарим за помощь.

1

Вы, кажется, не избегаете правильных значений = и @. Не уверен, что это единственная проблема.

Вы можете попробовать HttpUtility.UrlEncode.

+0

Как я могу выполнить URL-кодирование в .NET? – Simon

+0

Спасибо ... но все равно не удастся :( – Simon

+0

@Simon, сохраните свой код и выведите обновленный. –

Смежные вопросы