web-dev-qa-db-ja.com

ASP.NETでプログラム的にHTTP POSTをシミュレートする方法は?

HTTP POSTをプログラムでシミュレートする必要があります。つまり、いくつかのPOST変数を使用してリクエストを生成し、それをページに送信する必要があります。

明確にするために、プログラムですべてを行うのではなく、通常のPOSTの動作をシミュレートする必要があります。したがって、基本的には、フォームPOSTが発生した場合に入力されるのと同じ方法でリクエストを入力してから、POSTを期待するページにブラウザを送信する必要があります。

11
Farinha

これを行う1つの方法があります。

このメソッドに、URLと名前/値パラメーターをNameValueCollectionの形式で送信します。このメソッドは、エンドポイントでHttp Postを作成し、応答を文字列として返します。

もちろん、これを実行する内容/理由、およびこのメソッドが呼び出される回数によっては、他の方法もあります。ただし、特定のニーズに関する詳細情報を提供するまでは、この方法で十分です。

以下のメソッドはタスク(.NET 4.0)と非同期メソッドを使用するため、たとえばループで複数の呼び出しを行う場合は、次のコードリストのような同期メソッドよりも高速になります。

static string GetWebResponse(string url, NameValueCollection parameters)
{
  var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
  httpWebRequest.ContentType = "application/x-www-form-urlencoded";
  httpWebRequest.Method = "POST";

  var sb = new StringBuilder();
  foreach (var key in parameters.AllKeys)
    sb.Append(key + "=" + parameters[key] + "&");
  sb.Length = sb.Length - 1;

  byte[] requestBytes = Encoding.UTF8.GetBytes(sb.ToString());
  httpWebRequest.ContentLength = requestBytes.Length;

  using (var requestStream = httpWebRequest.GetRequestStream())
  {
    requestStream.Write(requestBytes, 0, requestBytes.Length);
    requestStream.Close();
  }

  Task<WebResponse> responseTask = Task.Factory.FromAsync<WebResponse>(httpWebRequest.BeginGetResponse, httpWebRequest.EndGetResponse, null);
  using (var responseStream = responseTask.Result.GetResponseStream())
  {
    var reader = new StreamReader(responseStream);
    return reader.ReadToEnd();
  }
}

webClientを使用することもできます(少し簡単です)。このメソッドは、postパラメータをフォームの文字列として想定しています

name1=value1&name2=value2&name3=value3

したがって、このメソッドを使用する場合は、必ずパラメータをそのまま渡すか、上記のコードのように実装を変更してください。

static string HttpPost(string url, string Parameters) 
{
   var req = System.Net.WebRequest.Create(url);       

   req.ContentType = "application/x-www-form-urlencoded";
   req.Method = "POST";
   byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
   req.ContentLength = bytes.Length;
   System.IO.Stream os = req.GetRequestStream ();
   os.Write (bytes, 0, bytes.Length);
   os.Close ();
   System.Net.WebResponse resp = req.GetResponse();
   if (resp== null)
     return null;
   var sr = new StreamReader(resp.GetResponseStream());
   return sr.ReadToEnd().Trim();
}
19
Shiv Kumar

このようなもの?

    public string DoFormPost(string Target, string PostData)
    {
        //Make a request            
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Target);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.AllowAutoRedirect = false;

        //Put the post data into the request
        byte[] data = (new ASCIIEncoding()).GetBytes(PostData);
        request.ContentLength = data.Length;
        Stream reqStream = request.GetRequestStream();
        reqStream.Write(data, 0, data.Length);
        reqStream.Close();

        //Get response
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();

        //Output response to a string            
        String result = "";
        using (Stream responseStream = response.GetResponseStream())
        {
            using (StreamReader reader = new StreamReader(responseStream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
                reader.Close();
            }
            return result;
        }
    }
3
Jon Egerton

やりたいことをするのは簡単ではないと思いますが、許容できる回避策があるかもしれません。回避策のアイデアは次のとおりです。

  • 投稿するフォームと一緒にJavaScriptをブラウザに返し、JavaScriptに投稿を依頼します。ただし、これは安全ではありません。
  • 宛先ページが制御下にある場合は、HttpContext.Current.Itemsを介してデータを渡し、Transferを呼び出して、宛先ページにその特殊なケースを認識させて処理させます。 HttpContext.Current.Itemsを使用する利点の1つは、セッション状態とは異なり、リクエストの終了時に自動的にクリアされることです。
  • HttpServerUtility.Executeは、別のページの結果を現在のページに埋め込みたい場合に役立ちます。フォームの投稿データやURLリクエストパラメータを設定することはできません。
  • 他の回答で説明されているようにHttpWebRequestを実行し、Response.Writeを使用してWebページからの応答として返します。また、ユーザーに認証資格情報とCookieを提供する必要がある場合もあります。 HttpWebRequest.CredentialsおよびHttpWebRequest.CookieContainerを参照してください。
  • 再要求されたときに同じ情報が表示されるように宛先ページを変更できる場合は、HttpWebRequestを実行し、その後にブラウザーのリダイレクトを実行できます。
  • どちらのページでも同じ出力を生成できるようにコードをリファクタリングします(例:共有UserControlまたはカスタムWebControlを使用)。
  • ページスクレイピングは、宛先ページが別のサイトにある場合に役立ちます。リクエストを行い、結果をスクレイプして、自分のページに結果を表示します。
1
user281806

私は過去にここでこの質問をしました:

プログラムでHTMLフォームをPOSTしますか?

私は私にとって素晴らしい働きをした次のリンクに導かれました!:

WebClient.UploadValues

1
Curt

HttpWebRequest クラスが必要です。

0