SMART LLC

.NETアプリケーションでPOSTデータを送受信する方法

公開日:2015/07/06

.NETアプリケーションでSOAP通信する方法に続き.NETで通信してみようシリーズ第二弾。
文字列やらファイルやらを.NETアプリからPOSTする方法を調べたのでメモする。

文字列のみの場合

文字列をPOST送受信するプログラム。

Dim url As String = "https://posttestserver.com/post.php"
Dim postData As String = "test1=aaa&test2=bbb&test3=ccc"
Dim wc As New System.Net.WebClient()
Dim enc As System.Text.Encoding = System.Text.Encoding.UTF8
wc.Encoding = enc
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded")
Dim res As String
res = wc.UploadString(url, postData)
wc.Dispose()
MsgBox(res)

書くのが面倒になったのでざっくりメモする。
WebClientクラス(System.Net名前空間)のオブジェクト用意して文字コードとContent-Type指定したらURLとPOSTする文字列をUploadStringメソッドでド━(゚Д゚)━ン!!
戻り値はStringなのであとはいい感じに(∀`*ゞ)テヘッ

ファイルをPOSTする場合

文字列とファイルをPOSTするプログラム。

Imports System.Net.Http
Dim url As String = "http://posttestserver.com/post.php"
Dim hc As New HttpClient
Dim data = New MultipartFormDataContent
data.Add(New StringContent("string1"), "param1")
data.Add(New StringContent("string2"), "param2")
data.Add(New ByteArrayContent(System.IO.File.ReadAllBytes("c:\temp\test.jpg")), "file", "test.jpg")
Dim res As HttpResponseMessage = Await hc.PostAsync(url, data)
MsgBox(Await res.Content.ReadAsStringAsync)

ファイルをアップロードする場合、multipart/form-dataの形式(POSTするデータをboundaryなるランダム文字列で区切る)でPOSTすることになるのだけど
調べてみるとそれを自前でランダム文字列生成してString変数boundaryに格納して…て記事がけっこう見つかる。
何かいい方法ないのって探してたら専用のMultipartFormDataContentクラス(System.Net.Http名前空間)が用意されてたので使ってみた。
WebClientクラスのかわりにHttpClientクラス(System.Net.Http名前空間)を使ってる。
文字列はStringContentクラス、ファイルはByteArrayContentクラスでaddしたらクライアントのPostAsyncメソッドでド━(゚Д゚)━ン!!
なんだけどAsync(非同期)のメソッドなので今回はAwaitをつけて別スレッドで結果が返るまで待ってから表示してる。
※Awaitがないと結果を待たずにTaskが返ってきて後続の処理に移る。
さらにAwaitを書くには自身もAsyncメソッドにする必要があった。
HttpResponseMessageクラスで受け取った受信内容はReadAsStringAsyncメソッドで読む。
あと今回は使わなかったけどStreamContentクラスてのもあってByteArrayContentクラスじゃなくてこれでもよさそうだった。

POSTデータの確認

実際にやりとりされるPOSTデータの内容はFiddlerを使った。

HttpClientでmultipart/form-dataでPOSTした送信データ。

POST http://posttestserver.com/post.php HTTP/1.1
Content-Type: multipart/form-data; boundary="ba266f94-55ff-4906-afc1-dd3dc9af131c"
Host: posttestserver.com
Content-Length: 31002
Expect: 100-continue
Connection: Keep-Alive

--ba266f94-55ff-4906-afc1-dd3dc9af131c
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=param1

string1
--ba266f94-55ff-4906-afc1-dd3dc9af131c
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=param2

string2
--ba266f94-55ff-4906-afc1-dd3dc9af131c
Content-Disposition: form-data; name=file; filename=test.jpg; filename*=utf-8''test.jpg

[画像ファイルのバイナリ部分は省略]
--ba266f94-55ff-4906-afc1-dd3dc9af131c--

これがmultipart/form-dataの形式。
各POSTパラメータはboundaryの先頭に「--」をつけた文字列で区切られてる。
最後は後ろにも「--」がつくらしい。

テストサーバにはHenry's HTTP Post Dumping Serverを使わせてもらった。
POST結果がわかる専用のページが生成されてそのURLが返ってくるというありがたいサービス。しかもmultipart/form-dataのファイルアップロードにも対応。
ヘンリーさんありがとう(∩´∀`)∩

さて、AwaitとかAsyncとか書いちゃったけど非同期処理についても理解しないとな…
受注きたらやろうPart2Ω\ζ°)チーン

SHARE