APIのテストにInsomniaを使用していますが、Postmanでも同じことが起こります。
次のコントローラーを使用して、ファイルのアップロードをテストしたいと思います。
public async Task<IActionResult> Post([FromForm]IFormFile File)
リクエストをマルチパートリクエストとして設定した場合:
できます。
ただし、バイナリファイルとして設定した場合:
データの取得方法がわかりません。どうすればできますか?
また、コントローラメソッドのシグネチャで、[FromForm]を[FromBody]に変更すると、データが取得されません。
誰かがこれを明確にしてくれますか?
すでにお気づきのように、Postman/Insomniaでbinary file
オプションを使用しても、標準的な方法では機能しません。 RESTful API経由でファイルをアップロードする方法は3つあり、いずれかを選択する必要があります。
アップロードされたファイルの内容を文字列に読み取って出力するコードスニペットを含めました。テキストファイルを送信してみると、200応答でファイルの内容を取得できます。
フォームデータのアップロード
これは、送信するデータをキー/値ペアのセットとしてフォーマットする最も一般的な/よく知られたアップロード方法です。通常、リクエストでContent-Type
〜multipart/form-data
を指定し、MVCで[FromForm]
属性を使用して値を変数にバインドする必要があります。また、組み込みのIFormFile
クラスを使用して、アップロードされたファイルにアクセスできます。
[HttpPost]
public async Task<IActionResult> PostFormData([FromForm] IFormFile file)
{
using (var sr = new StreamReader(file.OpenReadStream()))
{
var content = await sr.ReadToEndAsync();
return Ok(content);
}
}
ボディアップロード
MVCが理解できる形式で本文を送信できます。 JSON、そしてその中にファイルを埋め込みます。通常、ファイルのコンテンツはBase64または他のエンコードを使用してエンコードされ、特に画像やバイナリデータを送信する場合は、文字のエンコード/デコードの問題を回避します。例えば。
{
"file": "MTIz"
}
次に、コントローラー内で[FromBody]
を指定し、モデルの逆シリアル化にクラスを使用します。
[HttpPost]
public IActionResult PostBody([FromBody] UploadModel uploadModel)
{
var bytes = Convert.FromBase64String(uploadModel.File);
var decodedString = Encoding.UTF8.GetString(bytes);
return Ok(decodedString);
}
// ...
public class UploadModel
{
public string File { get; set; }
}
大きなテキスト以外のファイルを使用すると、JSONリクエストが不明瞭になり、読みにくくなります。
バイナリファイル
ここで重要なのは、ファイルが全体のリクエストであることです。リクエストには、MVCがコード内の変数に値をバインドするのに役立つ追加情報は含まれていません。したがって、ファイルにアクセスするには、Body
のRequest
を読み取る必要があります。
[HttpPost]
public async Task<IActionResult> PostBinary()
{
using (var sr = new StreamReader(Request.Body))
{
var body = await sr.ReadToEndAsync();
return Ok(body);
}
}