ROMANCE DAWN for the new world

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

ファイルをアップロードする API の Swagger ドキュメントを書く

ASP.NET Web API では、Swashbuckle を使って Swagger ドキュメントを作成します。
具体的な手順は、過去の記事を参照してください。
gooner.hateblo.jp

ASP.NET Web API で実装したファイルをアップロードする API のドキュメントを Swagger で書く方法を調べました。
multipart / form-data を使って、ファイルのバイナリデータを送信して、Azure Blob Storage にアップロードするシナリオです。

[HttpPost]
[Route("upload")]
public async Task<IHttpActionResult> Upload()
{
    if (Request.Content.IsMimeMultipartContent() == false)
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }
 
    var provider = await Request.Content.ReadAsMultipartAsync();
    var fileContent = provider.Contents.First(x => x.Headers.ContentDisposition.Name == JsonConvert.SerializeObject("buffer"));
    var buffer = await fileContent.ReadAsByteArrayAsync();
 
    var blob = this.container.GetBlockBlobReference("test.jpg");
    blob.Properties.ContentType = fileContent.Headers.ContentType.MediaType;
    await blob.UploadFromByteArrayAsync(buffer, 0, buffer.Length);
 
    return Ok();
}

Swagger ドキュメントをカスタマイズする

Swashbuckle の IOperationFilter インターフェイスを利用すると、Swagger メタデータ プロセスのさまざまな部分をカスタマイズできる拡張ポイントが提供されます。
IOperationFilter インターフェイスを継承した UploadFileOperationFilter クラスを実装しました。

public class UploadFileOperationFilter : IOperationFilter
{
	public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
	{
		operation.consumes.Add("multipart/form-data");
		operation.parameters = new[]
		{
			new Parameter
			{
				name = "buffer",
				@in = "formData",
				required = true,
				type = "file",
				description = "アップロードするファイル"
			},
		};
	}
}

Content-Type に multipart / form-data を追加し、パラメータを設定しています。入力形式に formData、タイプに file を指定するところが肝です。
そして、SwaggerOperationFilter 属性を使って、先ほどのアクションメソッドに UploadFileOperationFilter を指定します。

[HttpPost]
[Route("upload")]
[SwaggerOperationFilter(typeof(UploadFileOperationFilter))]
public async Task<IHttpActionResult> Upload()
{
}

Swagger ドキュメントでは、次のように表示され、参照ボタンからファイルを選択して API をテスト実行できます。

f:id:TonyTonyKun:20160920200609p:plain

まとめ

クエリパラメータや JSON のリクエストボディであれば、アクションメソッドの引数から Swashbuckle がドキュメントを作ってくれますが、ファイルアップロードの場合には、カスタムの OperationFilter を実装する必要があります。
まとまった情報がなく、トライアンドエラーした結果なので、もしかしたら別のアプローチがあるかもしれません。

追記:ASP.NET Core の場合

gooner.hateblo.jp