ASP.NET Core で Swashbuckle を使用し Web API を実装する場合、基本的に Controller にメソッドを追加するだけだが、ファイルアップロードする API を追加し UI から使えるようにする際はフィルタを使う必要がある。
/// <summary>
/// Swagger UI 用ファイルアップロードフィルタ
/// </summary>
public class UploadFileOperationFilter : IOperationFilter
{
/// <summary>
/// フィルタ適用
/// </summary>
/// <param name="operation">オペレーション</param>
/// <param name="context">コンテキスト</param>
public void Apply(Operation operation, OperationFilterContext context)
{
operation.Consumes.Add("multipart/form-data");
operation.Parameters = new IParameter[]
{
new NonBodyParameter()
{
Name = "file",
In = "formData",
Required = true,
Type = "file",
Description = "アップロードするファイル",
}
};
return;
}
}
このようなフィルタクラスを作り、アップロード API のメソッドに SwaggerOperationFilter
属性を介して指定する。
[Produces("application/json")]
[Route("api/v1/uploadfile")]
public class UploadController : Controller
{
[HttpPost]
[SwaggerOperationFilter(typeof(UploadFileOperationFilter))]
public async Task<IActionResult> UploadFile(IFormFile file)
{
// ここではオリジナルのファイル名の拡張子を取り出し
// 格納するときは GUID をベースの名前に変えている。
var orgFileName = ContentDispositionHeaderValue
.Parse(file.ContentDisposition)
.FileName.Trim('"');
var uploadFileName = Guid.NewGuid().ToString() + Path.GetExtension(orgFileName);
var url = await UploadToStorage(file.OpenReadStream(), uploadFileName);
return Json(url);
}
private async Task<string> UploadToStorage(Stream stream, string fileName)
{
// stream からデータを取り、
// それを適当なストレージに格納し、
// その URL を返す 処理を実装。
return "https://xxx.xxx.xxx/xxx/" + fileName;
}
}
UI ではこのような表示に。
[参照] にてファイルを指定して 送信すると、Response にアドレスが返る。
#先のサンプルコードでは、実際に保存する処理は実装していないですが。