2011-11-15 12 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つの情報を渡して結果を返そうとしています。ラベルで結果を確認したら、データを正規表現にするコードを書きます。 私は、4つのテキストボックスと送信ボタンを持つフォームに記入して、結果のページをスクラップしようとしています。 – Michael

答えて

5

プログラムでフォームを送信するには、一般的な考え方として、ブラウザを偽装する必要があります。これを行うには、サーバーを満たすために、URL、HTTPヘッダー、およびPOSTデータの適切な組み合わせを見つける必要があります。

サーバーが必要とするものを理解する最も簡単な方法は、Fiddler、FireBug、またはブラウザがワイヤを介して送信しているものを正確に調べるためのツールを使用することです。次に、サーバーが要求を受け入れるまで、ヘッダーを追加または削除したり、POSTデータを変更したりして、コード内で実験を行うことができます。ここで

は、あなたがに実行することがあり、いくつかの落とし穴です:

  • まず、あなたが右のターゲットURLにフォームを送信していることを確認してください。多くのフォームは自分自身には投稿しませんが、別のURLに投稿します
  • フォームは、セッションCookieまたは認証Cookieをチェックしている可能性があります。つまり、1回のリクエスト(Cookieを取得する)フォームを送信するためにその後のcookied要求を行います。
  • フォームに記入するのを忘れた隠しフィールドがある可能性があります。ブラウザで手動でフォームに入力するときに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をチェックしている可能性があります。つまり、1回のリクエスト( のCookieを取得)してからフォームを提出するクッキーリクエスト。

セッショントラッキングまたは認証用のCookieを使用するサーバーでは、Cookieが添付されていないリクエストが表示された場合、サーバーは通常、同じURLにリダイレクトします。リダイレクトにはSet-Cookieヘッダーが含まれます。つまり、リダイレクトされたURLが再要求されると、クライアントによって添付されたCookieが作成されます。サーバーやクライアントがPOSTのリダイレクトを処理していないため、最初の要求がPOSTの場合は、このアプローチが壊れます。

修正プログラムは、最初に説明したように、Cookieを取得するための最初のGETリクエストを作成し、POSTを2番目のリクエストとして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

恐ろしい答えがありがとう! 投稿URLが同じページであることを確認しました。 必要なフォームフィールドを確認しました。 私はPHPスクリプトを見ていますが、クッキーを参照するものは何も表示されません。それは$ _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'); ヘッダー( 'キャッシュ制御:ポストチェック= 0、事前チェック= 0'、偽)。 ヘッダー( 'Pragma:no-cache'); ' – Michael

関連する問題