質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

1回答

7501閲覧

POST(multipart/form-data)でEXCELファイルをアップロードする【VB.NET】

sena1111

総合スコア2

HTTP

HTTP(Hypertext Transfer Protocol)とはweb上でHTML等のコンテンツを交換するために使われるアプリケーション層の通信プロトコルです。

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

0クリップ

投稿2021/02/24 08:18

前提・実現したいこと

vb.netで、HTTPサーバーにPOST要求を行い、EXCELファイルを指定するURLアップロードしたいと考えています。
この際、ContentTypeは"multipart/form-data"を指定しています。

pdfのアップロードでは上手く行きますが、EXCELでは上手く行かず、躓いています。

発生している問題・エラーメッセージ

上手く行ったpdf用から、EXCEL用に変更するにあたり、以下のようにContent-Typeを変更しました。
"Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

これでEXCELにも対応できると考えたのですが、エラーとなります。(ソースコードの★ここで例外発生★の箇所)
他にも変更する必要がある箇所があるのでしょうか。
※アップロード先のサーバーからは、エラーコードnullで返ってきます。

該当のソースコード

VB.NET

1'送信するファイルのパス 2Dim filePath As String = "C:\sample1.xlsx" 3Dim fileName As String = System.IO.Path.GetFileName(filePath) 4'送信先のURL 5Dim url As String = "[送信先のURL]" 6'文字コード 7Dim enc As System.Text.Encoding = _ 8 System.Text.Encoding.GetEncoding("UTF-8") 9'区切り文字列 10Dim boundary As String = System.Environment.TickCount.ToString() 11 12'WebRequestの作成 13Dim req As System.Net.HttpWebRequest = _ 14 CType(System.Net.WebRequest.Create(url), _ 15 System.Net.HttpWebRequest) 16'メソッドにPOSTを指定 17req.Method = "POST" 18'ContentTypeを設定 19req.ContentType = "multipart/form-data; boundary=" + boundary 20 21'POST送信するデータを作成 22Dim postData As String = "" 23postData = "--" + boundary + vbCrLf + 24 "Content-Disposition: form-data; name=""path""" + vbCrLf + 25 vbCrLf + 26 "[アップロード先のパス]" + 27 vbCrLf + 28 "--" + boundary + vbCrLf + 29 "Content-Disposition: form-data; name=""name""" + vbCrLf + 30 vbCrLf + 31 "sample.xlsx" + 32 vbCrLf + 33 "--" + boundary + vbCrLf + 34 "Content-Disposition: form-data; name=""file""; filename=""sample.xlsx""" + vbCrLf + 35 "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" + vbCrLf + 36 vbCrLf '★ここをEXCEL用のContent-Typeに変更★ 37 38'バイト型配列に変換 39Dim startData As Byte() = enc.GetBytes(postData) 40postData = vbCrLf + "--" + boundary + "--" + vbCrLf 41Dim endData As Byte() = enc.GetBytes(postData) 42 43'送信するファイルを開く 44Dim fs As New System.IO.FileStream( _ 45 filePath, _ 46 System.IO.FileMode.Open, _ 47 System.IO.FileAccess.Read) 48 49'POST送信するデータの長さを指定 50req.ContentLength = startData.Length + endData.Length + fs.Length 51 52'データをPOST送信するためのStreamを取得 53Dim reqStream As System.IO.Stream = req.GetRequestStream() 54'送信するデータを書き込む 55reqStream.Write(startData, 0, startData.Length) 56'ファイルの内容を送信 57Dim readData(&H1000) As Byte 58Dim readSize As Integer = 0 59While True 60 readSize = fs.Read(readData, 0, readData.Length) 61 If readSize = 0 Then 62 Exit While 63 End If 64 reqStream.Write(readData, 0, readSize) 65End While 66fs.Close() 67reqStream.Write(endData, 0, endData.Length) 68reqStream.Close() 69 70'サーバーからの応答を受信するためのWebResponseを取得 71Dim res As System.Net.HttpWebResponse = _ '★ここで例外発生★ 72 CType(req.GetResponse(), System.Net.HttpWebResponse) 73応答データを受信するためのStreamを取得 74Dim resStream As System.IO.Stream = res.GetResponseStream() 75'受信して表示 76Dim sr As New System.IO.StreamReader(resStream, enc)

試したこと

以下サイトを参考にしています。
POSTでデータを送信する

Content-Typeは、以下を参考にEXCELに対応するものを設定しました。
Content-Type

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

Microsoft のドキュメントによると "重要 新しい開発には HttpWebRequest を使用しないことをお勧めします。 代わりに、System.Net.Http.HttpClient クラスを使用します" とのことです。multipart/form-data 形式にするのも面倒ですし。

HttpClient の利用をお勧めします。具体例は C# ですが以下の記事を見てください。

HttpClient でファイルアップロード
http://surferonwww.info/BlogEngine/post/2019/08/11/file-upload-by-using-httpclient.aspx

【追記】

下のコメント欄で「自分はコードのデバッグはできませんのでピンポイントでの問題点の指摘や解決策の提示はできませんが、ひょっとしたら役に立つかもしれない情報を回答欄に追記しておきます」と書いた件です。

pdfのアップロードでは上手く行きますが、EXCELでは上手く行かず、躓いています。

pdf ファイルは送信できているということですので、excel ファイルも送信はできているのではないかと思います。とすると、問題はサーバー側にあって、サイズの制限に引っかかっているとか、ヘッダー情報(Content-Type とか?)を見て制限をかけているということが怪しそうです。

送信できているかを確認するため Fiddler などのキャプチャツールを使って送信ヘッダとコンテンツを確認してください。

下の画像は、上に紹介した記事のアプリで「アンケート.xlsx」という excel ファイルを HttpWebRequest を利用して送信したときの送信ヘッダとコンテンツを Fiddler でキャプチャしたものです。記事ではコードは省略していますが、内容は質問者さんのものとほとんど同じ dobon.net のサンプルコードを使ってます。

イメージ説明

multipart 内のヘッダーの Content-Disposition, name, filename, Content-Type はコードに書いた通りのものに設定されていて、その下に .xlsx ファイルのバイト列が続いています。

サンプルコードは書き換えてないので Content-Type は image/jpeg のままで .xlsx ファイルの中身と違いますが、送信側の HttpWebRequest はそんなことは関知せず、指定した通りの内容で送信しているのが分かりますか?

質問者さんは Content-Type の設定をファイルの中身に合わせる必要があると考えているようですが、少なくとも送信するための条件にはならず、違っていても送信はされます。

サーバー側では送信されてきたバイト列を見てファイルの種類を判断することはできませんので、ファイルの種類を判断するなら filename の拡張子または Content-Type で判断することになります。

なので、それを見て特定の種類以外は拒否するということはできます。その前に、サイズ制限があってそこで引っかかっていれば拒否されるということがあるかもしれません。

ただ、そういう制限は一切してなくて、アップロードされてきたファイルをそのままサーバー側で保存するということももちろん可能です。以下の画像がその例で、ヘッダの filename に指定された名前「アンケート.xlsx」で保存されています。

イメージ説明

質問者さんがサーバー側も管理しているのであれば、そのあたりも調べてみてはいかがですか。

投稿2021/02/24 08:45

編集2021/02/25 03:21
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sena1111

2021/02/24 09:11

SurferOnWwwさん ご回答ありがとうございます。 重ねてのご質問となり恐縮ですが、質問に記載したコードの修正で、対応は出来ないでしょうか? ご回答への見解としては、以下の通りです。 >Microsoft のドキュメントによると… 私もこの記載を目にしましたが、今回は既存PRG(pdf用)を転用した改修としたいです。 >multipart/form-data 形式にするのも面倒ですし。 おっしゃる通りですが(私自身初心者のため、困惑しました)、送信先のwebAPIにmultipart/form-data形式との指定があります。
退会済みユーザー

退会済みユーザー

2021/02/24 09:35

> 質問に記載したコードの修正で、対応は出来ないでしょうか? であれば私はお役に立てません。コードのデバッグとか添削は私はできませんので、すみませんが、他の方の回答をお待ちください。
sena1111

2021/02/24 11:18

承知しました。ご回答いただきありがとうございました。
退会済みユーザー

退会済みユーザー

2021/02/25 02:39

レスがつきませんね。デバッグはできませんのでピンポイントでの問題点の指摘や解決策の提示はできませんが、ひょっとしたら役に立つかもしれない情報を回答欄に追記しておきます。
sena1111

2021/02/26 00:30

SurferOnWwwさん 詳細に追記いただきありがとうございます。 送受信についての基本的な理解が足りていない部分がありました。 >送信できているかを確認するため Fiddler などのキャプチャツールを使って送信ヘッダとコンテンツを確認してください。 fiddlerで確認したところ、やはり送信自体は出来ており、受信でエラーとなっているようです。 ご指摘いただきましたように、サーバー側を調べられる範囲で調べたところ、サイズやContent-Typeで制限をかけている箇所はわからなかったため、管理者に問い合わせようと思います。
退会済みユーザー

退会済みユーザー

2021/02/26 06:49

> 管理者に問い合わせようと思います。 何か分かったら情報提供いただけると幸いです。
退会済みユーザー

退会済みユーザー

2021/03/03 10:47

問い合わせ結果を書いてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問