ASP.NET HttpWebRequest POST到站点的麻烦

时间:2010-08-14 09:30:00

标签: c# asp.net .net-3.5 post httpwebrequest

ASP.NET 4.0

需要一些关于这个令人烦恼的HTTP POST问题的帮助 - 我已经查看了Stackoverflow上的其他帖子,但无济于事。

问题摘要:这是一个经典案例 - 我想登录到一个需要2个参数才能登录的外部网站,我需要使用POST来执行此操作

会发生什么:我执行POST并且返回的HTTP响应基本上与我首先发布的页面相同(即它尚未真正登录)

我做过的事情:我有fiddler(协议分析器)正在运行,我对我的POST和工作POST(来自另一个桌面应用程序)进行了比较,但我似乎无法重现相同的行为

[编辑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,但响应文本与我发布的页面相同 - 即登录页面,这表明我的帖子实际上没有成功。

现在这里是比较POSTS

a)来自我的申请(不工作)

POST https://[someURL] HTTP/1.1
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
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
Host: xxxx.com
Content-Length: 64
Expect: 100-continue
Connection: Keep-Alive

param1=value1&param2=value2

b)从工作的帖子(一个不同的桌面应用程序做同样的事情)

POST https:[someURL] HTTP/1.1
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, /
Referer: [someURL]
Accept-Language: en-US
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
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)
Host: xxxxxx.com
Content-Length: 2815
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: ccccc1=10; blahblah=pppqqqrrr; ASP.NET_SessionId=jp4mjg45z34si545om3nouew

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等) - 我如何访问它们以执行相同的操作?
  3. 我是否首先需要进行GET,解析身体,提取这些VIEWSTATE1-3& SomeField,然后在post body数据字节中重置它?我可以尝试很多东西,但如果有人告诉我,我是偏离轨道还是做了一些根本错误的事情,我会非常感激...

    我计划使用Html Agility包来解析HTML

    谢谢一堆, 克

1 个答案:

答案 0 :(得分:3)

问题可能是你需要提供一个会话cookie和你的登录请求。

您需要做的是首先向登录页面发出正常的GET请求。将所有响应cookie添加到CookieContainer,然后在进行实际的POST登录请求时使用相同的CookieContainer。

另外,尽可能尝试模仿真实的请求。使用相同的Referer值等。

看一下这个问题logged in to PureVolume.com programatically !

编辑:根据您尝试登录的网站的设计方式,您可能需要按照建议解析并提供ViewState数据。但由于最初的GET请求很可能已经是必需的,因此这应该不难做到。