Search code examples
c#asp.net-coreswaggerswagger-uiasp.net-core-webapi

How can I add an upload button to swagger UI in .NET core web api?


I have an ASP.net core web API with swagger (using swashbuckle).

One of the actions in the Web API is a file upload action:

[Produces("application/json")]
[Route("[controller]")]
public class FilesController : Controller
{
    [HttpPost]
    public void Post(IFormFile file)
    {
        ...
    }
}

When I look up that action in the swagger UI it let's me fill in all the fields of IFormFile, which is not what I want to do to test my API.

So how can I add an upload button to the Swagger UI?


Solution

  • First add a operation filter that consumes the multipart formdata.

    public class FileUploadOperation : IOperationFilter
    {
        private readonly IEnumerable<string> _actionsWithUpload = new []
        {
            //add your upload actions here!
            NamingHelpers.GetOperationId<FilesController>(nameof(FilesController.Post))
        };
    
        public void Apply(Operation operation, OperationFilterContext context)
        {
            if (_actionsWithUpload.Contains(operation.OperationId) )
            {
                operation.Parameters.Clear();
                operation.Parameters.Add(new NonBodyParameter
                {
                    Name = "file",
                    In = "formData",
                    Description = "Upload File",
                    Required = true,
                    Type = "file"
                });
                operation.Consumes.Add("multipart/form-data");
            }
        }
    }
    
        /// <summary>
        /// Refatoring friendly helper to get names of controllers and operation ids
        /// </summary>
        public class NamingHelpers
        {
            public static string GetOperationId<T>(string actionName) where T : Controller => $"{GetControllerName<T>()}{actionName}";
    
            public static string GetControllerName<T>() where T : Controller => typeof(T).Name.Replace(nameof(Controller), string.Empty);
        }
    

    Now you should add your actions to the _actionWithUpload array! Note that I added the extesnions only to have a refactoring friendly filter.

    Last but not least, make sure the operation filter is added to the options of swagger. So add options.OperationFilter<FileUploadOperation>(); to your swagger options and done.

    Full example:

           services.AddSwaggerGen(options =>
            {
                options.SwaggerDoc(Version, new Info
                    {
                        Title = Title,
                        Version = Version                        
                    }                
                );
                var filePath = Path.Combine(PlatformServices.Default.Application.ApplicationBasePath, $"{_webApiAssemblyName}.xml");
                options.IncludeXmlComments(filePath);
                options.DescribeAllEnumsAsStrings();
    //this is the step where we add the operation filter
                options.OperationFilter<FileUploadOperation>();
            });