ROMANCE DAWN for the new world

Microsoft Azure を中心とした技術情報を書いています。

ASP.NET Core Web API で multipart / form-data を使ってファイルをアップロードする

Azure Storage Blobs client library を使って Blob Storage にアクセスできますが、

  • クライアントに Azure Storage の情報を公開したくない
  • アプリケーション側でアクセスログを取りたい

といった要件があった場合、ASP.NET Core Web API を経由して Blob にアクセスさせることがあります。ファイルをアップロードする際には、Content-Type に multipart / form-data を使うことが多いです。
過去に ASP.NET の記事を書きましたが、その内容を ASP.NET Core にアップデートした内容となります。
gooner.hateblo.jp
gooner.hateblo.jp

Blob Storage へのアクセス

Azure Blob Storage SDK v12 を使用する方法をまとめたので、こちらの記事を参照してください。
gooner.hateblo.jp

Controller クラス

Controller クラスのコンストラクタでは、上記の記事で作成した Blob Storage にアクセスするクラスの FileRepository のインスタンスを DI で受け取ります。

[Route("api/[controller]")]
[Produces("application/json")]
[ApiController]
public class FilesController : ControllerBase
{
    private readonly IFileRepository _repository;

    public FilesController(IFileRepository repository)
    {
        _repository = repository;
    }
}

Blob にファイルをアップロードする

ASP.NET のときは、マルチパートのコンテンツを読み取るプロバイダークラスを使うなど面倒な実装が必要でした。
ASP.NET Core では、アップロードされたファイルが IFormFile に読み込まれるのでシンプルに実装できるようになりました。

public class UploadRequest
{
    public string FileName { get; set; }
    public IFormFile File { get; set; }
}
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> Upload([FromForm] UploadRequest upload)
{
    var fileName = upload.FileName;
    var file = upload.File;

    if (file.Length > 0)
    {
        using (var fileStream = file.OpenReadStream())
        {
            await _repository.UploadAsync(fileStream, fileName, file.ContentType);
        }
        return Ok();
    }
    return BadRequest();
}

Blob からファイルをダウンロードする

ダウンロードの API の場合は、FileContentResult の ActionResult を返します。

[HttpGet("{fileName}")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> DownloadAsync(string fileName)
{
    var fileContents = await _repository.DownloadAsync(fileName);
    return File(fileContents, "application/octet-stream", fileName);
}

Swagger ドキュメント

ASP.NET のときは、Swashbuckle の IOperationFilter インターフェイスを使うなど面倒な実装が必要でした。
gooner.hateblo.jp
ASP.NET Core では、IFormFile が引数に使われたアクションメソッドを判定して Swashbuckle 側で対応してくれるので、特別な実装は必要ありません。
Visual Studio でプロジェクトを作成する際に、Open API サポートを有効にする設定を行うだけで OK です。

f:id:TonyTonyKun:20211030170204p:plain