2011-11-15 21 views
1

我舉了一個用C#填寫表單的例子,但是當我運行代碼時,我只是再次返回頁面(就好像我沒有提交任何東西)。我嘗試手動去URL並添加?variable=value&variable2=value2,但似乎並沒有預先填寫表格,不知道這是爲什麼這不起作用。填寫表格C#和發佈錯誤

private void button2_Click(object sender, EventArgs e) 
{ 
    var encoding = new ASCIIEncoding(); 
    var postData = "appid=001"; 
    postData += ("&[email protected]"); 
    postData += ("&receipt=testing"); 
    postData += ("&machineid=219481142226.1"); 
    byte[] data = encoding.GetBytes(postData); 

    var myRequest = 
     (HttpWebRequest)WebRequest.Create("http://www.example.com/licensing/check.php"); 
    myRequest.Method = "POST"; 
    myRequest.ContentType = "application/x-www-form-urlencoded"; 
    myRequest.ContentLength = data.Length; 
    var newStream = myRequest.GetRequestStream(); 
    newStream.Write(data, 0, data.Length); 
    newStream.Close(); 

    var response = myRequest.GetResponse(); 
    var responseStream = response.GetResponseStream(); 
    var responseReader = new StreamReader(responseStream); 
    label2.Text = responseReader.ReadToEnd(); 
} 
+0

究竟是你想做些什麼?你是否試圖將表單數據保存到數據庫?或者是其他東西? –

+0

你想做什麼?您的問題文本意味着(至少對我而言)您正試圖在您正在編寫的應用程序中預填表格。但是您向我們展示的代碼只是創建一個POST請求到另一個頁面並顯示其響應。你能澄清嗎? – David

+0

check.php驗證許可證,所以我試圖將它傳遞給四條信息並返回結果,一旦我通過標籤確認結果,我將編寫代碼以將數據從其中重新排序。 因此,我試圖填寫一個有4個文本框和一個提交按鈕的表格,並將結果頁面刮掉。 – Michael

回答

5

要以編程方式提交表單,總體思路是要模擬瀏覽器。爲此,您需要找到正確的URL,HTTP標頭和POST數據組合以滿足服務器。

找出服務器需要的最簡單的方法是使用Fiddler,FireBug或其他工具,它可以讓您準確檢查瀏覽器通過電線發送的內容。然後,您可以通過添加或刪除標題,更改POST數據等在您的代碼中進行試驗,直到服務器接受請求。

這裏是你可能會遇到一些陷阱:

  • 首先,確保你提交表單到正確的目標URL。許多表單不會張貼到自己,但會張貼到不同的URL
  • 接下來,表單可能會檢查會話cookie或認證cookie,這意味着您需要提出一個請求(以獲取cookie)和然後進行後續的烹飪請求以提交表單。
  • 表單中可能有您忘記填寫的隱藏字段。使用Fiddler或Firebug查看在瀏覽器中手動填寫表單時提交的表單字段,並確保在您的代碼中包含相同的字段
  • 取決於在服務器上執行,你可能需要將@字符編碼爲%40

可能有過其他挑戰,但上面是最有可能。要查看完整列表,請查看my answer到另一個屏幕截圖問題。

順便說一句,你用來提交表單的代碼比需要的更加困難和冗長。相反,您可以使用WebClient.UploadValues()並使用較少的代碼和自動完成的編碼完成相同的事情。就像這樣:

NameValueCollection postData = new NameValueCollection(); 
postData.Add ("appid","001"); 
postData.Add ("email","[email protected]"); 
postData.Add ("receipt","testing"); 
postData.Add ("machineid","219481142226.1"); 
postData.Add ("checkit","checkit"); 

WebClient wc = new WebClient(); 
byte[] results = wc.UploadValues (
         "http://www.example.com/licensing/check.php", 
         postData); 
label2.Text = Encoding.ASCII.GetString(results); 

UPDATE:

鑑於我們在評論中討論,你正在運行到的問題是我上面提到最初的原因之一:

該表單可能正在檢查會話cookie或身份驗證Cookie,這意味着您需要提出一個請求(以獲取cookie的 ),然後進行後續烹飪請求提交表格。

在使用cookie進行會話跟蹤或身份驗證的服務器上,如果請求顯示時沒有附加cookie,服務器通常會重定向到同一個URL。重定向將包含一個Set-Cookie標題,這意味着當重新請求重定向的URL時,它將具有由客戶端附加的cookie。如果第一個請求是POST表單,此方法就會中斷,因爲服務器和/或客戶機不處理POST的重定向。

正如我最初所描述的那樣,此修復程序會進行初始GET請求來提取cookie,然後將您的POST作爲第二個請求傳回cookie。

像這樣:

using System; 

public class CookieAwareWebClient : System.Net.WebClient 
{ 
    private System.Net.CookieContainer Cookies = new System.Net.CookieContainer(); 

    protected override System.Net.WebRequest GetWebRequest(Uri address) 
    { 
     System.Net.WebRequest request = base.GetWebRequest(address); 
     if (request is System.Net.HttpWebRequest) 
     { 
      var hwr = request as System.Net.HttpWebRequest; 
      hwr.CookieContainer = Cookies; 
     } 
     return request; 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var postData = new System.Collections.Specialized.NameValueCollection(); 
     postData.Add("appid", "001"); 
     postData.Add("email", "[email protected]"); 
     postData.Add("receipt", "testing"); 
     postData.Add("machineid", "219481142226.1"); 
     postData.Add("checkit","checkit"); 

     var wc = new CookieAwareWebClient(); 
     string url = "http://www.example.com/licensing/check.php"; 

     // visit the page once to get the cookie attached to this session. 
     // PHP will redirect the request to ensure that the cookie is attached 
     wc.DownloadString(url); 

     // now that we have a valid session cookie, upload the form data 
     byte[] results = wc.UploadValues(url, postData); 
     string text = System.Text.Encoding.ASCII.GetString(results); 
     Console.WriteLine(text); 
    } 
} 
+0

真棒回答謝謝你! 我驗證了帖子的網址是相同的頁面。 我驗證了所需的表單字段。 我正在查看PHP腳本,但沒有看到任何引用cookie的內容。它需要$ _POST並分割斜槓並使用它來構建一個mySQL查詢。 我嘗試了兩個逐字字符串,並使用%40作爲@。 去看看你的其他答案。 – Michael

+0

我在答案的開頭添加了幾段文字,以澄清在尋找答案時要遵循的整體方法。 –

+0

我嘗試了列表中的所有內容,但是標題,php腳本非常簡單,但我確實看過並在腳本中看到以下標題。這些會導致您提及的代碼存在任何問題嗎? 'header('Expires:Mon,1997年7月26日05:00:00 GMT'); ('Cache-Control:no-store,no-cache,must-revalidate'); header('Cache-Control:post-check = 0,pre-check = 0',FALSE); header('Pragma:no-cache');' – Michael