
http://xxxx.xxx.xx.xx/filedataへ複数のファイル送信を行いたいのですが、うまくいきません。
以下のサイトを参考にしました。
https://ouipanda.hatenablog.com/entry/20090716/1247757511
データ受信側はDjangoRestFrameWorkで作成されています。
Postmanでhttp://xxxx.xxx.xx.xx/filedataへfomr-dataのkeyとValueを設定し、POSTしたところなんの問題もなく
送信&受信する事が出来ました。
パラメータはこんな感じです。
{
"id": "",
"title": "",
"pdf_file": "",
"csv_file": "",
}
ファイルを一つだけPOSTする場合は問題なく行えるのですが二つともファイルを送るとなると上手く行きません。
↓実際のコード
string url = "http://localhost:8000/api/filedata/"; List<string> files = new List<string>(); files.Add("C:\\file\TEST_BOOK1.csv"); files.Add("C:\\file\TEST.pdf"); List<string> fileNames = new List<string>(); fileNames.Add("pdf_file"); fileNames.Add("csv_file"); string tick = Environment.TickCount.ToString(); System.Text.Encoding enc = System.Text.Encoding.UTF8; WebRequest req = WebRequest.Create(url); req.Method = "POST"; req.ContentType = "multipart/form-data; boundary=" + tick; byte[] boundary = enc.GetBytes("--" + tick); byte[] crlf = enc.GetBytes("\r\n"); List<byte[]> headers = new List<byte[]>(); string header = ""; //ヘッダの作成とデータサイズの計算 long contentLen = 0; for (int i = 0; i < files.Count; i++) { //ヘッダ header = "--" + tick + "\r\n" + "Content-Disposition: form-data; name=\"" + fileNames[i] + i.ToString() + "\"; filename=\"" + Path.GetFileName(files[i]) + "\"\r\n" + "Content-Type: application/octet-stream\r\n" + "Content-Transfer-Encoding: binary\r\n\r\n"; headers.Add(enc.GetBytes(header)); //1ファイルごとのデータサイズ contentLen += headers[i].Length + new FileInfo(files[i]).Length; } //全体のデータサイズ req.ContentLength = contentLen + ((boundary.Length + crlf.Length + crlf.Length) * files.Count) + boundary.Length; //送信 using (Stream reqStream = req.GetRequestStream()) { for (int i = 0; i < files.Count; i++) { //送信ファイル using (FileStream fs = new FileStream(files[i], FileMode.Open, FileAccess.Read)) { //ヘッダ reqStream.Write(boundary, 0, boundary.Length); reqStream.Write(crlf, 0, crlf.Length); reqStream.Write(headers[i], 0, headers[i].Length); //ファイル内容 byte[] buf = new byte[0x1000]; int readSize = 0; while (true) { readSize = fs.Read(buf, 0, buf.Length); if (readSize == 0) break; reqStream.Write(buf, 0, readSize); } reqStream.Write(crlf, 0, crlf.Length); } } reqStream.Write(boundary, 0, boundary.Length); WebResponse res = req.GetResponse(); } }
追記
上手く行かない→
--boundary Content-Disposition: form-data; name="フォーム1"; filename="ファイル1" Content-Type: application/octet-stream Content-Transfer-Encoding: binary --boundary Content-Disposition: form-data; name="フォーム2"; filename="ファイル2" Content-Type: application/octet-stream Content-Transfer-Encoding: binary
というようにヘッダーの内容を記述し、送信したときに。
フォーム1に指定のファイルがPOSTされることは確認できるのですが、フォーム2へのPOSTが確認できない。
フォーム2への送信処理がとばされているのかと思ったのですが、Fiddlerを使い、内容を確認したところそういうわけでは無さそうです。
Postmanで送信したときの内容とプログラムから送信したときの内容を見比べてみました。
同じcsvファイルをPOSTしているのは確認がしやすいようにです、ファイル形式が違うため上げることが出来ないなどはありません。
Postmanの方は末尾に"--"が付いていますが、これは処理に関係あるのでしょうか?
以下 プログラムから送信したときの内容
--96403343 Content-Disposition: form-data; name="title" テスト --96403343 Content-Disposition: form-data; name="user" test --96403343 Content-Disposition: form-data; name="category" 1 --96403343 Content-Disposition: form-data; name="checked" False --96403343 Content-Disposition: form-data; name="pdf_file"; filename="Book1.csv" Content-Type: application/octet-stream Content-Transfer-Encoding: binary 11818818 18118 99999 --96403343 Content-Disposition: form-data; name="csv_file"; filename="Book1.csv" Content-Type: application/octet-stream Content-Transfer-Encoding: binary 11818818 18118 99999 --96403343
以下Postmanから送信したときの内容
----------------------------228829904362102449550779 Content-Disposition: form-data; name="title" test114 ----------------------------228829904362102449550779 Content-Disposition: form-data; name="csv_file"; filename="Book1.csv" Content-Type: text/csv 11818818 18118 99999 ----------------------------228829904362102449550779 Content-Disposition: form-data; name="pdf_file"; filename="Book1.csv" Content-Type: text/csv 11818818 18118 99999 ----------------------------228829904362102449550779--
コードの方も少し変えました
//送信先のURL string url = "http://localhost:8000/api/filedata/"; //送信対象のCSVファイルのパスと名前 string filePath = "C:\\tmp_file\\nest1\\Book1.csv"; string fileName = Path.GetFileName(filePath); //送信対象のPDFファイルのパスと名前 string pdffilePath = "C:\\tmp_file\\nest1\\Book1.csv"; string pdffileName = Path.GetFileName(pdffilePath); //パラメータ設定 string title = "テスト"; string user = "test"; // int category = 1; bool check = false; // string tick = Environment.TickCount.ToString(); System.Text.Encoding enc = System.Text.Encoding.UTF8; //WebRequestの生成 WebRequest req = WebRequest.Create(url); req.Method = "POST"; req.ContentType = "multipart/form-data; boundary=" + tick; byte[] boundary = enc.GetBytes("--" + tick); byte[] crlf = enc.GetBytes("\r\n"); List<byte[]> headers = new List<byte[]>(); //全体のヘッダー string postheader = "--" + tick + "\r\n" + "Content-Disposition: form-data; name=\"title\"\r\n\r\n" + title + "\r\n" + "--" + tick + "\r\n" + "Content-Disposition: form-data; name=\"user\"\r\n\r\n" + user + "\r\n" + "--" + tick + "\r\n" + "Content-Disposition: form-data; name=\"category\"\r\n\r\n" + category + "\r\n" + "--" + tick + "\r\n" + "Content-Disposition: form-data; name=\"checked\"\r\n\r\n" + check + "\r\n"; //ヘッダの作成とデータサイズの計算 long contentLen = 0; contentLen += enc.GetBytes(postheader).Length; string pdfheader = "Content-Disposition: form-data; name=\"pdf_file\"; filename=\"" + pdffileName + "\"\r\n" + "Content-Type: text/csv\r\n\r\n"; contentLen += boundary.Length + crlf.Length + enc.GetBytes(pdfheader).Length + new FileInfo(pdffilePath).Length + crlf.Length; string csvheader = "Content-Disposition: form-data; name=\"csv_file\"; filename=\"" + fileName + "\"\r\n" + "Content-Type: text/csv\r\n\r\n" + "--" + tick + "--\r\n"; contentLen += boundary.Length + crlf.Length + enc.GetBytes(csvheader).Length + new FileInfo(filePath).Length;// + crlf.Length; //全体のデータサイズ req.ContentLength = contentLen + boundary.Length; //送信 using (Stream reqStream = req.GetRequestStream()) { //全体のヘッダ reqStream.Write(enc.GetBytes(postheader), 0, enc.GetBytes(postheader).Length); using (FileStream pdfFs = new FileStream(pdffilePath, FileMode.Open, FileAccess.Read)) { //pdf部ヘッダ reqStream.Write(boundary, 0, boundary.Length); reqStream.Write(crlf, 0, crlf.Length); reqStream.Write(enc.GetBytes(pdfheader), 0, enc.GetBytes(pdfheader).Length); //ファイル内容 byte[] pdfbuf = new byte[0x1000]; int pdfreadSize = 0; while (true) { pdfreadSize = pdfFs.Read(pdfbuf, 0, pdfbuf.Length); if (pdfreadSize == 0) break; reqStream.Write(pdfbuf, 0, pdfreadSize); } reqStream.Write(crlf, 0, crlf.Length); } using (FileStream csvFs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) { //csv部ヘッダ reqStream.Write(boundary, 0, boundary.Length); reqStream.Write(crlf, 0, crlf.Length); reqStream.Write(enc.GetBytes(csvheader), 0, enc.GetBytes(csvheader).Length); //ファイル内容 byte[] csvbuf = new byte[0x1000]; int csvreadSize = 0; while (true) { csvreadSize = csvFs.Read(csvbuf, 0, csvbuf.Length); if (csvreadSize == 0) break; reqStream.Write(csvbuf, 0, csvreadSize); } reqStream.Write(crlf, 0, crlf.Length); } reqStream.Write(boundary, 0, boundary.Length);





回答1件
あなたの回答
tips
プレビュー