top of page

Testing file upload with Swagger in ASP.Net core

Let’s assume you have an API which is used for uploading image to the backend and you wanted to test it when the UI is still in development.

[HttpPost("UploadImage")]
public ActionResult UploadImage()
{
   IFormFile file = HttpContext.Request.Form.Files[0];
   _logger.LogInformation(file.FileName);   
   // we can put rest of upload logic here.
   return Ok();
}

So first thing is you do is to check swagger UI and to your surprise you didn’t see the way to upload the file in swagger UI.


So then how will you test.

there are couple of ways by which we can achieve this.

In this tutorial, we are going to look at them.

Let’ start by making some changes in API first.

Accept IFormFile as Parameter first way is to change the API to accept IFormFile as parameter.

[HttpPost("UploadImage")]
public ActionResult UploadImage(IFormFile file)
{
   
   _logger.LogInformation(file.FileName);// we can put rest of upload logic here.
   return Ok();
}

Now ran the app again and see the swagger UI.


Now we can see upload file button and we can test now.

Accept Multiple files as parameter

Change the code to accept multiple files.

[HttpPost("UploadMultipleImages")]
public ActionResult UploadMultipleImages(IFormFile[] files)
{
   foreach (var item in files)
   {
        _logger.LogInformation("file uploaded : " + item.FileName);
   }
   // we can rest of upload logic here.   return Ok();
}

Now run the app


We can now add multiple files and upload them together.


The second way..

In case we don’t want to change the API signature and keep it in the same way.

[HttpPost("UploadImage")]
public ActionResult UploadImage()

It is still possible to test with swagger but we have to add some code explicitly.

Let’ start by adding class called “FileUploadFilter

and add the following code.

public class FileUploadFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext 
    context)  
    {
        var formParameters = context.ApiDescription.ParameterDescriptions            
            .Where(paramDesc => paramDesc.IsFromForm());
        
        if(formParameters.Any())	
        {
            // already taken care by swashbuckle. no need to add 
            explicitly.
            return;	
        }
        if(operation.RequestBody!=null)	
        {
            // NOT required for form type
            return;	
        }
        if (context.ApiDescription.HttpMethod == HttpMethod.Post.Method)        
        {
            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}            
           };        
       }   
    
    }
}   

public static class Helper
{
       internal static bool  IsFromForm(this ApiParameterDescription 
       apiParameter)    
   {
       var source = apiParameter.Source;
       var elementType = apiParameter.ModelMetadata?.ElementType;
   
       return (source == BindingSource.Form || source == 
       BindingSource.FormFile) || (elementType != null && 
       typeof(IFormFile).IsAssignableFrom(elementType));    
   }
}

also add the following code to ConfigureServices method

services.AddSwaggerGen(options =>
{
   options.OperationFilter<FileUploadFilter>();
});

Now let’s run the app and see the swagger UI.


We can see the possibility to add the file in request from swagger UI.


Source code can be found at here


Summary

Testing file uploads with swagger UI can be useful when you want to test your API without writing any other client to send the file.



Source: Medium - Nitesh Singhal


The Tech Platform

Comments


bottom of page