How can I add an upload button to swagger UI in .N

2019-05-27 11:30发布

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?

2条回答
欢心
2楼-- · 2019-05-27 12:08

In addition to @Nick's answer, I have to make 2 changes for AspNet core 2.

1] Updated GetOperationId()

Now all operationIds contain API prefix as well as Method in the suffix. So I have statically added API & Post in ActionName.

public static string GetOperationId<T>(string actionName) where T : ControllerBase => $"Api{GetControllerName<T>()}{actionName}Post";

2] Remove only file parameter

Instead of removing all parameters for that action, I want to remove only the file parameter.

var fileParameter = operation.Parameters.FirstOrDefault(x => x.Name == "file" && x.In == "body");
if (fileParameter != null)
{
    operation.Parameters.Remove(fileParameter);
    ...
}
查看更多
淡お忘
3楼-- · 2019-05-27 12:13

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>();
        });
查看更多
登录 后发表回答