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

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

新規登録して質問してみよう
ただいま回答率
87.20%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ChatWork

業務の効率化を目的としたコミュニケーションツール。 グループチャット、ビデオ・音声通話、ファイル共有、タスク管理などの機能を備えています。マルチデバイス対応で、ブラウザだけでなくタブレットやスマートフォンでも利用可能です。

解決済

C# で ChatWork にエクセルファイルをアップロードしたい

Com
Com

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ChatWork

業務の効率化を目的としたコミュニケーションツール。 グループチャット、ビデオ・音声通話、ファイル共有、タスク管理などの機能を備えています。マルチデバイス対応で、ブラウザだけでなくタブレットやスマートフォンでも利用可能です。

1回答

0評価

0クリップ

25閲覧

投稿2019/03/11 10:27

編集2022/01/12 10:58

C# で ChatWorkにエクセルファイルをアップロードしたく下記のコードを実行しましたら
ファイルのアップロードには成功するのですが、ファイルが壊れてしまいます。
※一応ここにそうように作成しました。
http://developer.chatwork.com/ja/endpoint_rooms.html#POST-rooms-room_id-files
どなたか、ご教授いただきたく何卒よろしくお願いいたします。

※このコードはとりあえずテキストファイルをアップしています。

static void Main(string[] args) { FileSendExe(); } static void FileSendExe() { // テストファイル string filePath = @"デスクトップ\test.txt"; // 表示する添付ファイル名 string filename = "test.txt"; // ルーム番号 string roomID = "000000000"; // トークン string apikey = "**************************************"; // 拡張子に対応したコンテンツタイプ string _type = Contents_type(filePath); // 文字コードを指定する var enc = Encoding.GetEncoding("UTF-8"); // UP先URL string url = string.Format("https://api.chatwork.com/v2/rooms/{0}/files", roomID); // 単に起動から現在までの時間を取得 string boundary = System.Environment.TickCount.ToString(); // インスタンス var req = WebRequest.Create(url); // メソッドをPOSTに設定 req.Method = "POST"; // コンテンツタイプをファイルに設定 req.ContentType = "multipart/form-data; boundary=" + boundary; //POST送信するデータを作成 string postData = ""; postData = "--------------------------" + boundary + "\r\n" + "Content-Disposition: form-data; name=\"file\"; filename=\"" + filename + "\"\r\n" + "Content-Type: " + _type + "\r\n\r\n"; // 送信するファイルを開く System.IO.FileStream fs = new System.IO.FileStream( filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read); // 読取準備 System.IO.BinaryReader br = new System.IO.BinaryReader(fs); // ファイルをバイナリで読み取る byte[] readData = br.ReadBytes((Int32)fs.Length); fs.Close(); var _postData = enc.GetBytes(postData).ToList(); _postData.AddRange(readData); // メッセージ追加 postData = "--------------------------" + boundary + "\r\n"; postData += "Content-Disposition: form-data; name=\"message\"\r\n\r\n"; postData += "I attached comment to chat.\r\n"; postData += "--------------------------" + boundary + "--"; _postData.AddRange(enc.GetBytes(postData)); // 送信バイナリデータの長さを指定 req.ContentLength = _postData.Count(); // トークン設定 req.Headers.Add(string.Format("X-ChatWorkToken: {0}", apikey)); // データをPOST送信するためのStreamを取得 System.IO.Stream reqStream = req.GetRequestStream(); // POSTで書込み //reqStream.Write(_postData, 0, _postData.Length); reqStream.Write(_postData.ToArray(), 0, _postData.Count); // 書込みストリームを閉じる reqStream.Close(); // サーバーからの応答を受信する System.Net.HttpWebResponse res = (System.Net.HttpWebResponse)req.GetResponse(); // 応答データを受信するためのStreamを取得 var resStream = res.GetResponseStream(); // 受信して表示 var sr = new StreamReader(resStream, enc); // 結果受信 var responseMessage = sr.ReadToEnd(); }

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

y_waiwai
y_waiwai

2019/03/11 10:34

まずは元のファイルとどこがどういうふうに違うのかを調べてください。そして、その結果を提示しましょう
Com
Com

2019/03/11 10:39

ありがとうございます。 元のエクセルファイルには、セルA1に「TEST」と入力したものがあり、 アップロード後のエクセルファイルを開きますと、 「ファイル形式またはファイル拡張子が正しくありません。」とエラーのポップが出て エクセルが正しく開かないのです。
y_waiwai
y_waiwai

2019/03/11 10:44

その元ファイルとアップロード後のやつをバイナリ比較して、どこがどういうふうに違うのかを調べてみよう
Zuishin
Zuishin

2019/03/11 10:53

BitConverter\.ToString すると 12-34-56 のような形式のテキストになりますが、これに対応してるんでしょうか? Base64 とか octet-stream でなくていいんですか?
Zuishin
Zuishin

2019/03/11 10:57

https://github\.com/yoheiMune/frontend-playground/tree/master/024-multipart-form-data#post-body-1 調べてみると、バイナリをテキスト化せずそのまま入れるみたいですね。
Com
Com

2019/03/11 11:45

y_waiwaiさん いつもありがとうございます。アップロード前のファイルバイト数は8859で アップロード後のファイルバイト数は17720で全く別物でしたー。 Zuishinさん ありがとうございます! そのまま入れるとは。。。。? テキストファイルなんかだとわかるのですが、 イメージファイルも同じくでしょうか?
Zuishin
Zuishin

2019/03/11 12:12

Stream なので BinaryWriter で書き込むのがいいと思います。
Com
Com

2019/03/12 03:36

Zuishinさん ありがとうございます。 調べてみましたのですが自己解決できませんでした。 StringにBinaryWriter でバイナリを書き込むということでしょうか?
Zuishin
Zuishin

2019/03/12 03:38

String ではなく Stream です。 > // データをPOST送信するためのStreamを取得
Com
Com

2019/03/12 04:43

Zuishinさん ありがとうございます。 ファイルアップはされましたが結果は同じでした。 試しにファイルのバイナリデータの部分だけを reqStream\.Write\(_postData, 0, _postData\.Length\); ↓ foreach\(byte _b in readData\)  reqStream\.WriteByte\(_b\); とし、他をStream で書き込んでみましたら、ファイルがアップされず無反応でした。 (エラーは出ませんでした。)
Zuishin
Zuishin

2019/03/12 04:47

その Stream をファイルの Stream に差し替えて、実際にフォーマットに従ったファイルになるかどうか確かめてみてください。 アップロードするかわりにファイルに書き込むということです。
Com
Com

2019/03/12 05:11

Zuishinさん ありがとうございます。 試しに中身が「あいうえお」のテキストファイルをプログラムの記載内容でバイナリ取得して それをFileStreamで別名ファイルに書込みましたら、正しく「あいうえお」テキストファイルが復元されました。
Zuishin
Zuishin

2019/03/12 05:20

ヘッダが無かったのなら間違ってますね。
Com
Com

2019/03/12 05:22

Zuishinさん ありがとうございます。 ヘッダというのは、------- で始まる部分のことでしょうか?
Zuishin
Zuishin

2019/03/12 05:27

それも含めて全部です。サーバーに送るフォーマットになっているかどうか確かめてください。
Com
Com

2019/03/12 05:39

Zuishinさん ありがとうございます。 なるほど!すみません、先ほどはファイルのバイナリ部分だけを書き込んでました。 全て含めたバイナリをテキストファイルに書き込みますと中身はこうなっておりました。 --------------------------678522765 Content-Disposition: form-data; name="file"; filename="test\.txt" Content-Type: text/plain 82A082A282A482A682A8 --------------------------678522765--
Zuishin
Zuishin

2019/03/12 05:48

それでアップロードするとどうなりますか?
Com
Com

2019/03/12 05:49

チャットワーク上に中身が「82A082A282A482A682A8」 と記載された、テキストファイルがアップされるのです。
Zuishin
Zuishin

2019/03/12 05:50

あと > 82A082A282A482A682A8 これはテキストのように見えますが、バイナリになっていますか?
Zuishin
Zuishin

2019/03/12 05:51

それなら成功です。 バイナリをテキスト化しているので、あとはそれをバイナリのまま書き込むだけです。 現在のコードを質問を編集して追記してください。
Com
Com

2019/03/12 07:05 編集

はい。更新できました。
Com
Com

2019/03/12 07:41

Zuishinさんの話を再考して、再度コードを書き換えました。 結果テキストファイルは正しくアップロードされました! 次にエクセルファイルをアップロードしますと、前回までは拡張子が違うとアナウンスされましたが 今回は、「一部の内容に問題が見つかりました。可能な限り内容を回復しますか?」 と、おしいところまで進みました! (回復しても開けませんでした。。。)
Zuishin
Zuishin

2019/03/12 07:46

それをダウンロードしてオリジナルとどこが違うか比較してみてください。 Excel だと比較が難しいかもしれないので、半角文字のみの UTF8 テキストファイルで試すのが良いかもしれません。ファイルサイズや改行コードなども比べてください。
Com
Com

2019/03/12 08:28

Zuishinさん ありがとうございます。 「abcde」と記載したテキストファイルをUTF-8で作成して比較してみました。 バイナリの比較ですが、 作成前 EF-BB-BF-61-62-63-64-65 作成後 EF-BB-BF-61-62-63-64-65-0D-0A と、おっしゃる通り末尾に 0D-0A の改行コードが追加されていました。 一応確認しましたが、アップ時点ではファイルバイナリに改行コードは付いておりません。 これ、対策方法ってあるのでしょうか。。。?
Zuishin
Zuishin

2019/03/12 08:31

バイナリのすぐ後に改行を挿入していたのを削除しました。 バイナリ直後のバウンダリの中の "\\r\\n" がそれです。 これを外してやってみてください。
Com
Com

2019/03/12 09:00

Zuishinさん ありがとうございます! 正しくアップロードできました! あと、下に書いてくれていたの先ほど気づきました。。。生意気に編集してしまったようなコードなので ご指導いただいたコードに修正して、アップロードが完成したものに書き換えました。 根気強くお付き合いいただきまして誠にありがとうございます。感謝です!
Com
Com

2019/03/12 09:03

あと、少し変更点ありました。 最後の頭の改行コードを抜くと、テキストファイルの中身がこうなってしまいまして、 abcde--------------------------690051812 Content-Disposition: form-data; name="message" I attached comment to chat\. メッセージを追加して、そのバウンダリの頭に改行コードを入れると成功いたしました。 postData = "\\r\\n\(←コレ\)--------------------------" \+ boundary \+ "\\r\\n";  postData \+= "Content-Disposition: form-data; name=\\"message\\"\\r\\n\\r\\n"; ありがとうございました!
Zuishin
Zuishin

2019/03/12 09:04

成功してなによりです。

まだ回答がついていません

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

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ChatWork

業務の効率化を目的としたコミュニケーションツール。 グループチャット、ビデオ・音声通話、ファイル共有、タスク管理などの機能を備えています。マルチデバイス対応で、ブラウザだけでなくタブレットやスマートフォンでも利用可能です。