宇宙仮面の C# プログラミング
   

Top

C# 2005

C# 2003

C# Windows Mobile

SQL Server 2005

SQL Server 2000

Virtual PC/Server

C# 研究室ブログ

C# ソフトウェア ダウンロード

C# 開発環境

宇宙仮面の C# プログラミングについて

.NET/C# eGroup JP

INETA Japan



Google
Web
uchukamen.com









HTML POST (同期と非同期パターン)

開発環境: Visual Studio 2003 

1.目次

2.目的

Web アクセス時の POSTの方法を同期、非同期でそれぞれまとめました。
非同期は、マニュアルもタコだし、いいページもないしで、備忘録が必要なのでメモっています。

3.参考書

(1) GotDotNet サンプル: ”タスクの例 : POST 要求を作成する”

4.同期 HTML POST アクセスパターン

郵政公社の郵便番号検索ページは POST で作られています。
次のサンプルは、郵便番号から住所を検索する POST 処理を同期で行う場合のサンプルコードです。
同期で POST する場合のパターン
using System;
,,,,
using System.Diagnostics;
using System.Net;
using System.Web;
using System.IO;
using System.Text;
....

        // 郵便番号→住所のためのURL
        private const string Zip2AddressURL = "http://search.post.japanpost.jp/7zip/zip.cgi";

        private void Post()
        {
            System.IO.Stream  stream = null;
            System.IO.StreamReader sr = null;
            try 
            {
                System.Net.WebRequest webReq = HttpWebRequest.Create( Zip2AddressURL );
                webReq.Method = "POST"; 
                // 1秒でタイムアウトさせる。
                webReq.Timeout = 1000; 
                // IE のProxy 設定を使用する。
                webReq.Proxy = System.Net.WebProxy.GetDefaultProxy();
                // デフォルトのコンテントタイプ
                webReq.ContentType = "application/x-www-form-urlencoded"; 
                // POST パラメータを書く。

                // 正確なパラメータを渡すために HttpUtility.UrlEncode()でエンコードする。
                string parameters = "mode=search&start=0&end=400&keyword=";
                parameters += HttpUtility.UrlEncode( "111-");
                parameters += "&new=on";

                // Ascii なので、エンコーディングは指定する必要なし。
                Stream reqStream = webReq.GetRequestStream();
                StreamWriter sw = new StreamWriter(reqStream);
                sw.Write(parameters);
                sw.Close();

                // 結果を受け取る。
                WebResponse webRes = webReq.GetResponse();
                // HttpWebRequest からストリームを取得する。
                stream = webRes.GetResponseStream();
                // SHIFT JIS で読み取る。
                sr = new StreamReader(stream, Encoding.GetEncoding("SHIFT-JIS"));
                String str = null;
                
                str = sr.ReadToEnd();
                Debug.WriteLine( str );
            } 
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
            }
            finally
            {
                if (sr != null) sr.Close();
                if (stream != null) stream.Close();
            }
        }
      

5.非同期 HTML POST アクセスパターン


1から書こうとするとはまるんですよねぇ。。。
郵政公社の郵便番号検索ページは POST で作られています。
次のサンプルは、郵便番号から住所を検索する POST 処理を非同期で行う場合のサンプルコードです。
非同期で POST する場合のパターン
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Text;
using System.IO;
using System.Net;
using System.Web;
using System.Diagnostics;
using System.Threading;
....

        // 郵便番号→住所のためのURL
        private const string Zip2AddressURL = "http://search.post.japanpost.jp/7zip/zip.cgi";

        public void WriteCallBack(IAsyncResult ar)
        {
            Debug.WriteLine("WriteCallBack");

            HttpWebRequest req = (HttpWebRequest) ar.AsyncState;

            Encoding enc = System.Text.Encoding.GetEncoding("SHIFT-JIS");
            StreamWriter sw = new StreamWriter(req.EndGetRequestStream(ar), enc);

            // 正確なパラメータを渡すために HttpUtility.UrlEncode()でエンコードする。
            string parameters = "mode=search&start=0&end=400&keyword=";
            parameters += HttpUtility.UrlEncode( "111-");
            parameters += "&new=on";

            sw.Write(parameters);
            sw.Close();
            
            Debug.WriteLine("WriteCallBack End");
        }

        public void ReadCallBack(IAsyncResult ar)
        {
            Debug.WriteLine("ReadCallBack");

            HttpWebRequest req = (HttpWebRequest) ar.AsyncState;
            HttpWebResponse response = (HttpWebResponse) req.EndGetResponse(ar);

            Encoding enc = System.Text.Encoding.GetEncoding("SHIFT-JIS");
            StreamReader sr = new StreamReader(response.GetResponseStream(), enc);

            string str = sr.ReadToEnd();
            Debug.WriteLine(str);
            sr.Close();
            
            Debug.WriteLine("ReadCallBack End");
        }

        private void Request()
        {
            try
            {
                Debug.WriteLine("Start");
                WebRequest webReq = HttpWebRequest.Create( Zip2AddressURL );
                // 1秒でタイムアウトさせる。
                webReq.Timeout = 1000; 
                // IE のプロキシ設定を使用する。
                webReq.Proxy = System.Net.WebProxy.GetDefaultProxy(); 
                webReq.Method = "POST";
                webReq.ContentType = "application/x-www-form-urlencoded";
                                
                // 非同期要求に対するコールバックを設定します。
                AsyncCallback writeCallBack = new AsyncCallback(this.WriteCallBack); 
                // 非同期で要求します。
                IAsyncResult r = webReq.BeginGetRequestStream(writeCallBack, webReq);

                // 待つ場合
                r.AsyncWaitHandle.WaitOne();
                ///////////////////////////////////////////////


                // 非同期要求に対するコールバックを設定します。
                AsyncCallback readCallBack = new AsyncCallback(this.ReadCallBack); 
                // 非同期で要求します。
                IAsyncResult rAr = webReq.BeginGetResponse(readCallBack, webReq);
                // 待つ場合
                rAr.AsyncWaitHandle.WaitOne();
                while(! rAr.IsCompleted)
                    Debug.Write(".");
                Debug.WriteLine("Finished");
            }
            catch (Exception exc)
            {
                // わかりやすいメッセージに変える。
                throw(new WebException("xxxに接続できませんでした。" + exc.Message));
            }
        }

6.ソースコード

変更履歴
2003/5/26初版作成 V1.0 同期POST.cs、非同期POST.cs
2004/3/21タイムアウト値が1000秒になっていたのを修正。>> m_ _ m Unyoraさん
同期POST.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Diagnostics;
using System.Net;
using System.Web;
using System.IO;
using System.Text;

namespace HTMLPost
{
    /// <summary>
    /// Form1 の概要の説明です。
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button button1;
        /// <summary>
        /// 必要なデザイナ変数です。
        /// </summary>
        private System.ComponentModel.Container components = null;

        public Form1()
        {
            //
            // Windows フォーム デザイナ サポートに必要です。
            //
            InitializeComponent();

            //
            // TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
            //
        }

        /// <summary>
        /// 使用されているリソースに後処理を実行します。
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

                #region Windows Form Designer generated code
        /// <summary>
        /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディタで変更しないでください。
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(136, 72);
            this.button1.Name = "button1";
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.ClientSize = new System.Drawing.Size(292, 266);
            this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                          this.button1});
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }
                #endregion

        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            Post();
        }

        // 郵便番号→住所のためのURL
        private const string Zip2AddressURL = "http://search.post.japanpost.jp/7zip/zip.cgi";

        // 住所→郵便番号のためのURL(かな検索)
        private const string Address2ZipURL = "http://search.post.japanpost.jp/7zip/kana.cgi";

        private void Post()
        {
            System.IO.Stream  stream = null;
            System.IO.StreamReader sr = null;
            try 
            {
                System.Net.WebRequest webReq = HttpWebRequest.Create( Zip2AddressURL );
                webReq.Method = "POST"; 
                // 1秒でタイムアウトさせる。
                webReq.Timeout = 1000; 
                // IE のProxy 設定を使用する。
                webReq.Proxy = System.Net.WebProxy.GetDefaultProxy();
                // デフォルトのコンテントタイプ
                webReq.ContentType = "application/x-www-form-urlencoded"; 
                // POST パラメータを書く。

                // 正確なパラメータを渡すために HttpUtility.UrlEncode()でエンコードする。
                string parameters = "mode=search&start=0&end=400&keyword=";
                parameters += HttpUtility.UrlEncode( "111-");
                parameters += "&new=on";

                // Ascii なので、エンコーディングは指定する必要なし。
                Stream reqStream = webReq.GetRequestStream();
                StreamWriter sw = new StreamWriter(reqStream);
                sw.Write(parameters);
                sw.Close();

                // 結果を受け取る。
                WebResponse webRes = webReq.GetResponse();
                // HttpWebRequest からストリームを取得する。
                stream = webRes.GetResponseStream();
                // SHIFT JIS で読み取る。
                sr = new StreamReader(stream, Encoding.GetEncoding("SHIFT-JIS"));
                String str = null;
                
                str = sr.ReadToEnd();
                Debug.WriteLine( str );
            } 
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
            }
            finally
            {
                if (sr != null) sr.Close();
                if (stream != null) stream.Close();
            }
        }
    }
}
非同期Post.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Text;
using System.IO;
using System.Net;
using System.Web;
using System.Diagnostics;
using System.Threading;


namespace HTMLPutAsync
{
    /// <summary>
    /// Form1 の概要の説明です。
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button button1;
        /// <summary>
        /// 必要なデザイナ変数です。
        /// </summary>
        private System.ComponentModel.Container components = null;

        public Form1()
        {
            //
            // Windows フォーム デザイナ サポートに必要です。
            //
            InitializeComponent();

            //
            // TODO: InitializeComponent 呼び出しの後に、コンストラクタ コードを追加してください。
            //
        }

        /// <summary>
        /// 使用されているリソースに後処理を実行します。
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

                #region Windows Form Designer generated code
        /// <summary>
        /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
        /// コード エディタで変更しないでください。
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(120, 56);
            this.button1.Name = "button1";
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 12);
            this.ClientSize = new System.Drawing.Size(292, 266);
            this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                                                          this.button1});
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }
                #endregion

        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            Request();
        }

        // 郵便番号→住所のためのURL
        private const string Zip2AddressURL = "http://search.post.japanpost.jp/7zip/zip.cgi";

        public void WriteCallBack(IAsyncResult ar)
        {
            Debug.WriteLine("WriteCallBack");

            HttpWebRequest req = (HttpWebRequest) ar.AsyncState;

            Encoding enc = System.Text.Encoding.GetEncoding("SHIFT-JIS");
            StreamWriter sw = new StreamWriter(req.EndGetRequestStream(ar), enc);

            // 正確なパラメータを渡すために HttpUtility.UrlEncode()でエンコードする。
            string parameters = "mode=search&start=0&end=400&keyword=";
            parameters += HttpUtility.UrlEncode( "111-");
            parameters += "&new=on";

            sw.Write(parameters);
            sw.Close();
            
            Debug.WriteLine("WriteCallBack End");
        }

        public void ReadCallBack(IAsyncResult ar)
        {
            Debug.WriteLine("ReadCallBack");

            HttpWebRequest req = (HttpWebRequest) ar.AsyncState;
            HttpWebResponse response = (HttpWebResponse) req.EndGetResponse(ar);

            Encoding enc = System.Text.Encoding.GetEncoding("SHIFT-JIS");
            StreamReader sr = new StreamReader(response.GetResponseStream(), enc);

            string str = sr.ReadToEnd();
            Debug.WriteLine(str);
            sr.Close();
            
            Debug.WriteLine("ReadCallBack End");
        }

        private void Request()
        {
            try
            {
                Debug.WriteLine("Start");
                WebRequest webReq = HttpWebRequest.Create( Zip2AddressURL );
                // 1秒でタイムアウトさせる。
                webReq.Timeout = 1000; 
                // IE のプロキシ設定を使用する。
                webReq.Proxy = System.Net.WebProxy.GetDefaultProxy(); 
                webReq.Method = "POST";
                webReq.ContentType = "application/x-www-form-urlencoded";
                                
                // 非同期要求に対するコールバックを設定します。
                AsyncCallback writeCallBack = new AsyncCallback(this.WriteCallBack); 
                // 非同期で要求します。
                IAsyncResult r = webReq.BeginGetRequestStream(writeCallBack, webReq);

                // 待つ場合
                r.AsyncWaitHandle.WaitOne();
                ///////////////////////////////////////////////


                // 非同期要求に対するコールバックを設定します。
                AsyncCallback readCallBack = new AsyncCallback(this.ReadCallBack); 
                // 非同期で要求します。
                IAsyncResult rAr = webReq.BeginGetResponse(readCallBack, webReq);
                // 待つ場合
                rAr.AsyncWaitHandle.WaitOne();
                Debug.WriteLine("Finished");
            }
            catch (Exception exc)
            {
                // わかりやすいメッセージに変える。
                throw(new WebException("xxxに接続できませんでした。" + exc.Message));
            }
        }
    }
}
このページを評価する

このページを評価する

悪い             良い
1 2 3 4 5
コメント(一言お願いします)