HTML POST (同期と非同期パターン)
開発環境: Visual Studio 2003
- 目次
- 目的
- 参考書
- 同期 HTML POST アクセスパターン
- 非同期 HTML POST アクセスパターン
- ソースコード
Web アクセス時の POSTの方法を同期、非同期でそれぞれまとめました。
非同期は、マニュアルもタコだし、いいページもないしで、備忘録が必要なのでメモっています。
-
GotDotNet
サンプル: ”タスクの例 : 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();
}
}
|
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));
}
}
|
変更履歴 |
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));
}
}
}
}
|