公開日: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Ω\ζ°)チーン