#使用環境
C#
.NET 4.0 (NugetでMicrosoft.Net.Httpをインストール済み)
※たぶん4.5以降も同じです。
#やりたかったこと
WebApiをコンソールアプリから呼び出したかったんです。
でもWebClientクラスでは1回のPOST送信で複数ファイル送れないじゃない!
HttpClientならできる?でも.NET4.5以降のものだしなぁ・・・
と思ったらNugetで配信されてた(Microsoftさんありがとう!)
#ファイル送信ソース
こちらさんの記事を参考にしながら下記を記述
using (var httpClient = new HttpClient())
using (var multipart = new MultipartFormDataContent())
{
var finfo = new FileInfo(filePath); // ここは指定のファイルをどうぞ
var fileContent = new StreamContent(File.OpenRead(finfo.FullName));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
Name = "file1", // ここは任意の名前で
FileName = finfo.Name
}
multipart.Add(fileContent);
// 送信
var postAsyncTask = httpClient.PostAsync(reqestUrl, multipart);
postAsyncTask.Wait(); // async/awaitは.NET4.0だから使えない...
var responseMessage = postAsyncTask.Result;
}
ちなみに今回は"サンプルファイル.xlsx"というファイル名のファイルを送信している。
##すると受け取り先で...
ファイル名が文字化け!
↓こんな感じ
=?utf-8?B?44K144Oz44OX44Or44OV44Kh44Kk44OrLnhsc3g=?=
#対策
いろいろと調べると、勝手にHttpClientくんがファイル名とかを含んだContentDispositionをエンコードしちゃうらしい。
おそらくBase64でエンコードされる。
そこでStack Overflowくんのこの記事を参考にして、対策をおこなう。
using (var httpClient = new HttpClient())
using (var multipart = new MultipartFormDataContent())
{
var finfo = new FileInfo(filePath); // ここは指定のファイルをどうぞ
// 手動でエンコードを行う。
string headerValue = string.Format("form-data; name=\"{0}\"; filename=\"{1}\"", "file1", finfo.Name);
byte[] headerValueByteArray = Encoding.UTF8.GetBytes(headerValue);
var encodingHeaderValue = new StringBuilder();
foreach (byte b in headerValueByteArray)
{
encodingHeaderValue.Append((char)b);
}
fileContent.Headers.Add("Content-Disposition", encodingHeaderValue.ToString());
multipart.Add(fileContent);
// 送信
var postAsyncTask = httpClient.PostAsync(reqestUrl, multipart);
postAsyncTask.Wait(); // async/awaitは.NET4.0だから使えない...
var responseMessage = postAsyncTask.Result;
}
自分のつたない英語力では「こんな感じで先にエンコードしてやるんやで」
ぐらいのニュアンスしかつかめなかったが、とりあえずこれで文字化けしなかったのでよしとする。
#結論
HttpClientくんが余計なことをしてるので、こんな感じでやってあげよう。
もしかしたらNugetでHttpClientやWebClientの不便な部分を埋めると多分ヒットすると思う。(自分はむり)
先人の方たちの記事に感謝