Беда с ASP.NET HttpWebRequest POST к сайту - PullRequest
4 голосов
/ 14 августа 2010

ASP.NET 4.0

Нужна помощь в решении этой неприятной проблемы HTTP POST - я просматривал другие сообщения о Stackoverflow, но безрезультатно.

Краткое описание проблемы : Это классический случай - я хочу войти на внешний сайт, который принимает 2 параметра для входа, и мне нужно использовать POST для этого

Что происходит : я делаю POSTи ответ HTTP, который возвращается, по сути, является той же самой страницей, на которой я сначала разместил (то есть он на самом деле не вошел в систему)

То, что я сделал: У меня естьзапущен fiddler (анализатор протокола), и у меня есть сравнения моего POST и рабочего POST (из другого настольного приложения), но я не могу воспроизвести такое же поведение

[edit 1]: Кажется, это проблема с файлами cookie (приведенный ниже код устарел, я внес изменения), мне удалось правильно настроить все параметры.Проблема не решена на момент этого редактирования.

Ниже приведен мой код и я также воспроизвел заголовки сравнения

 private static void doPost(string URL)
    {
        HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(URL);
        myRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.126 Safari/533.4";
        CookieContainer cCookie = new CookieContainer();
        myRequest.CookieContainer = cCookie;
        myRequest.ContentType = "application/x-www-form-urlencoded";
        myRequest.Accept = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";            

        string postData = "param1=somevalue&param2=someothervalue";
        ASCIIEncoding ascii = new ASCIIEncoding();
        byte[] bData = ascii.GetBytes(postData);

        myRequest.Method = "POST";
        myRequest.ContentLength = bData.Length;

        Stream oStream = myRequest.GetRequestStream();
        oStream.Write(bData, 0, bData.Length);

        string oResp = string.Empty;

        using (var resp = myRequest.GetResponse())
        {
            using (var responseStream = resp.GetResponseStream())
            {
                using (var responseReader = new StreamReader(responseStream))
                {
                    oResp = responseReader.ReadToEnd();
                }
            }
        }
        Console.WriteLine(oResp);        
    }

Я получил HTTP 1.1 OK, но текст ответа тот жестраница, на которой я размещен - то есть страница входа в систему, которая предполагает, что мое сообщение на самом деле не было успешным.

Теперь вот сравнение ПОЗИЦИИ

a) ИЗ МОЕЙ ЗАЯВКИ (НЕ РАБОТАЕТ)

POST <a href="https://[someURL]" rel="nofollow noreferrer">https://[someURL]</a> HTTP/1.1<br/> User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.126 Safari/533.4<br/> Content-Type: application/x-www-form-urlencoded<br/> Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,<em>/</em>;q=0.5<br/> Host: xxxx.com<br/> Content-Length: 64<br/> Expect: 100-continue<br/> Connection: Keep-Alive<br/> <br/> param1=value1&param2=value2<br/>

b) ИЗ ПОЧТЫ, КОТОРЫЙ РАБОТАЕТ (РАЗНОЕ DOSTTOP APP, ДЕЙСТВУЮЩЕЕ ТО ЖЕ ВСЕ)

POST https:[someURL] HTTP/1.1 <br/> Accept: image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, <em>/</em> <br/> Referer: [someURL] <br/> Accept-Language: en-US <br/> Content-Type: application/x-www-form-urlencoded <br/> Accept-Encoding: gzip, deflate <br/> User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; Tablet PC 2.0; InfoPath.2; .NET4.0C; .NET4.0E) <br/> Host: xxxxxx.com<br/> Content-Length: 2815<br/> Connection: Keep-Alive<br/> Cache-Control: no-cache<br/> Cookie: ccccc1=10; blahblah=pppqqqrrr; ASP.NET_SessionId=jp4mjg45z34si545om3nouew <br/><br/></p> <p>SomeField=False&__VIEWSTATE1=1H4sIAA3mnn8A%2F31WTbequfx[TRUNCATED]jF%2FLkgCgAA&__VIEWSTATE0=3&__VIEWSTATE=&__VIEWSTATE=&param1=value1&param2=value2&x=0&y=0

Как вы можете видетьвторой POST намного больше - ключевые различия:

  1. Есть некоторые куки, тогда как у меня нет никаких
  2. В заголовке POST показаны эти дополнительные поля (SomeField, VIEWSTATE1и т. д.) - как мне получить к ним доступ, чтобы сделать то же самое?

Нужно ли сначала выполнить GET, проанализировать тело, извлечь эти VIEWSTATE1--3 и SomeField, а затем сбросить его в байтах данных тела сообщения?Я мог бы попробовать много вещей, но было бы очень признательно, если бы кто-нибудь сказал мне, если я не в порядке или я делаю что-то в корне неправильно ...

Я планирую использовать пакет Html Agility для анализа HTML1048 *

спасибо, куча, г

1 Ответ

3 голосов
/ 14 августа 2010

Проблема, вероятно, заключается в том, что вам необходимо предоставить cookie сеанса вместе с запросом на вход.

Что вам нужно сделать, это сначала сделать обычный запрос GET на страницу входа. Добавьте все куки-файлы ответа в ваш CookieContainer, а затем используйте тот же CookieContainer, когда выполняете фактический запрос входа в систему POST.

Кроме того, старайтесь максимально имитировать реальный запрос. Используйте то же значение Referer и т. Д.

Посмотрите на этот вопрос Вы вошли на PureVolume.com программно!

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

...