Handling file uploads in Open API with ASP.NET Core

This post is about implementing handling file uploads in Open API with ASP.NET Core. Open API is one way to document REST API endpoints. When we using Web API and IFormFile class to upload a file, Open API will display a File Upload control in the UI like this.

Here is the action method.

app.MapPost(“/upload”, async (IFormFile file) =>
{
//Do something with the file
return Results.Ok();
}).Accepts<IFormFile>(“multipart/form-data”).Produces(200);

Which will render something like this.

Earlier versions of Open API won’t render it properly. And if we are using multiple IFormFile elements this won’t work properly. Here is an example.

app.MapPost(“/upload-multiple”, async (IFormFile[] files) =>
{
//Do something with the files
return Results.Ok();
}).Accepts<IFormFile[]>(“multipart/form-data”).Produces(200);

Which will result something like this.

And if we not using IFormFile and using Request.Form object to receive file upload then also it will not render properly. We can fix this by introducing a custom OperationFilter implementation. Here is the code to manage multiple files.

public class FileUploadOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var fileUploadMime = “multipart/form-data”;
if (operation.RequestBody == null ||
!operation.RequestBody.Content.Any(x =>
x.Key.Equals(fileUploadMime, StringComparison.InvariantCultureIgnoreCase)))
{
return;
}
var name = context.ApiDescription.ActionDescriptor.DisplayName;
operation.Parameters.Clear();
if (context.ApiDescription.ParameterDescriptions[0].Type != typeof(IFormFile))
{
var uploadFileMediaType = new OpenApiMediaType()
{
Schema = new OpenApiSchema()
{
Type = “object”,
Properties =
{
[“files”] = new OpenApiSchema()
{
Type = “array”,
Items = new OpenApiSchema()
{
Type = “string”,
Format = “binary”
}
}
},
Required = new HashSet<string>() { “files” }
}
};

operation.RequestBody = new OpenApiRequestBody
{
Content = { [“multipart/form-data”] = uploadFileMediaType }
};
}
}
}

And we can include this in the UI like this.

builder.Services.AddSwaggerGen(setup =>
{
setup.OperationFilter<FileUploadOperationFilter>();
}

Which will render something like this – clicking on Add string item button will add File Upload controls.

We can modify the FileUploadOperationFilter code and use the same code if you’re using Request.Form to accept files in the server side.

Happy Programming 🙂

Leave a Reply

Your email address will not be published.