Skip to main content
upload file via Swagger in ASP.NET Core Web API

How to upload file via Swagger in ASP.NET Core Web API

Swagger is a simple, clean and powerful representation of your RESTful API. Once integrated with WEB API, it provides a UI which helps in testing the API with ease. In my earlier post, I explained about how to integrate swagger with the ASP.NET Core Web API. And it works great with all HTTP verbs and input parameters. But uploading a file via Swagger is not straightforward. In this post, let’s find out how to upload file via Swagger in ASP.NET Core Web API.

Upload file via Swagger in ASP.NET Core Web API

Before you read further, please read my post and know how to add swagger to your ASP.NET Core project. Now let’s add a method to your controller, which take IFromFile as input parameter. IFromFile represents a file sent with the HttpRequest and it is available in the Microsoft.AspNet.Http namespace. For the demo, this method is added to default controller (ValuesController) available with default ASP.NET Core Web API template.

[HttpPost]
[Route("upload")]
public void PostFile(IFormFile uploadedFile)
{
   //TODO: Save file
}

And now when you run the application and navigate to upload method, you will see the following.

How to upload file via Swagger in ASP.NET Core

Instead of file upload control, you see multiple input boxes. Well, these are properties of IFromFile which represents the uploaded file. But, you can’t upload file with these input boxes. Rather, a file upload control will make your life simple. Let’s find out how to get file upload control, instead of these input boxes.

Swashbuckle has IOperationFilter which allows to post-modify operation descriptions once they’ve been generated by wiring up one or more Operation filters. Implementing this filter will provide the option to modify or replace the operation parameters. To implement IOperationFilter, let’s add a class FileUploadOperation which implement this filter. IOperationFilter has only one method called Apply to implement.

public class FileUploadOperation : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (operation.OperationId.ToLower() == "apivaluesuploadpost")
        {
            operation.Parameters.Clear();
            operation.Parameters.Add(new NonBodyParameter
            {
                Name = "uploadedFile",
                In = "formData",
                Description = "Upload File",
                Required = true,
                Type = "file"
            });
            operation.Consumes.Add("multipart/form-data");
        }
    }
}

This filter will replace the multiple input boxes with file upload control. The above code does following things.

  • It first checks for operation with OperationId as “apivaluesuploadpost“. The operationId name is a combination of couple of parameters. It is made up of “api” + [Controller name] + [Method Name] + [HTTP Verb].
    Or in other words, it is the URL of your controller method, but without “/” + [HTTP Verb].
  • It clears all the parameters. So all the properties of IFromFile interface are cleared.
  • And then adds custom parameters to the operation. Please note, the Name parameter value must be equal to parameter name to the method. So in this case, it is “uploadedFile” PostFile(IFormFile uploadedFile). In property must be set to “formData” and Type must be “file”.
  • Finally, consume type multipart/form-data which is required for file transfer from client to server.

And final step is to register this operation filter in Startup.cs.

services.AddSwaggerGen();
services.ConfigureSwaggerGen(options =>
{
    options.SingleApiVersion(new Info
    {
        Version = "v1",
        Title = "My API",
        Description = "My First Core Web API",
        TermsOfService = "None",
        Contact = new Contact() { Name = "Talking Dotnet", Email = "contact@talkingdotnet.com", Url = "www.talkingdotnet.com" }
    });
    options.IncludeXmlComments(GetXmlCommentsPath());
    options.DescribeAllEnumsAsStrings();
    options.OperationFilter<FileUploadOperation>(); //Register File Upload Operation Filter
});

Now when you run the application and navigate to Upload method. And you should see following.

How to upload file via Swagger in ASP.NET Core Web API

There is a file upload control and all the parameters that we configured are also present on UI (as highlighted in the image). When you select a file to upload and navigate to VS in debugging mode, you can see IFormFile object holds the uploaded file.

How to upload file via Swagger in ASP.NET Core Web API-2

That’s it.

To sum up things, to support file uploading via Swagger UI, IOperationFilter provided by SwashBuckle needs to be implemented to modify post operation description for the web API method which supports file uploading.

Thank you for reading. Keep visiting this blog and share this in your network. Please put your thoughts and feedback in the comments section.

PS: If you found this content valuable and want to return the favour, then Buy Me A Coffee

19 thoughts to “How to upload file via Swagger in ASP.NET Core Web API”

      1. There is no “IFormFile” implementation on .net framework. Can you explain that how can we upload file via Swagger in .NET Framework (for example 4.6.1).
        Please help us.

  1. Thank you so much for your post.
    I can put the button to browse a file but unfortunately i can’t execute the upload file with sucess.
    I’m receiving the message “Error: Unsupported Media Type” but i don’t know where i can specify the suported type accepted by this field.

    Could you help me, please?

    Best regards!

  2. Hi, I’ve updated this sample to have something more generic.

    public class FileUploadOperation : IOperationFilter
    {
    public void Apply(Swashbuckle.AspNetCore.Swagger.Operation operation, OperationFilterContext context)
    {
    // only take methods having a paremeter of IFileForm type
    var fileUploadParameters = context.ApiDescription.ParameterDescriptions.Where(p => p.ModelMetadata.ElementType == typeof(IFormFile));
    // if none, out
    if (!fileUploadParameters.Any())
    return;
    // We iterate on every parameters found
    for (int i = 0; i p.Name == fileUploadParameter.Name);
    operation.Parameters.Remove(parameter);

    //if the parameter is of Collection type (list, ienumerable, …), we create multiple upload fields
    var fileUploadCount = (fileUploadParameter.ModelMetadata.IsCollectionType ? 3 : 1);

    for (int j = 0; j < fileUploadCount; j++) { operation.Parameters.Add(new NonBodyParameter { Name = fileUploadParameter.Name, In = "formData", Description = "Upload File", Required = fileUploadParameter.ModelMetadata.IsRequired, Type = "file" }); } operation.Consumes.Add("multipart/form-data"); } } }

      1. If it help anyone coming across this answer now, I believe the code this person was trying to add was:

        public void Apply(Operation operation, OperationFilterContext context)
        {
        var fileUploadParameters = context.ApiDescription.ParameterDescriptions
        .Where(p => p.ModelMetadata.ElementType == typeof(IFormFile));

        if (!fileUploadParameters.Any())
        return;

        //Iterate over the parameters found that match IFormFile and remove them from the operation.
        foreach(var parameter in fileUploadParameters)
        {
        var removeParam = operation.Parameters.Where(s => s.Name == parameter.Name).FirstOrDefault();
        if(removeParam != null)
        operation.Parameters.Remove(removeParam);

        var fileUploadCount = parameter.ModelMetadata.IsCollectionType ? 3 : 1;
        for(int j = 0; j < fileUploadCount; j++)
        {
        operation.Parameters.Add(new NonBodyParameter
        {
        Name = parameter.Name,
        In = "formData",
        Description = "Upload File",
        Required = parameter.ModelMetadata.IsRequired,
        Type = "File"
        });
        operation.Consumes.Add("multipart/form-data");
        }
        }
        }

  3. This Controller’s method is ‘IFormFile’,if the Controller’s method is ‘List’,these code still can work ,but I can only select one file,How does we give the add a ‘multiple’ property?

    1. Madhukar,

      I am also not getting the multiple input box now, probably things changed either in Swagger or in ASP.NET Core but once you add the filter, it is working. I can see the file upload control. Are you getting any error while implementing the filter?

Leave a Reply

Your email address will not be published. Required fields are marked *