我有一个带有swagger的ASP.net核心Web API(使用swashbuckle)。
Web API中的一个操作是文件上载操作:
[Produces("application/json")]
[Route("[controller]")]
public class FilesController : Controller
{
[HttpPost]
public void Post(IFormFile file)
{
...
}
}
当我在swagger UI中查找该动作时,让我填写IFormFile
的所有字段,这不是我想要测试我的API。
那么如何在Swagger UI中添加上传按钮呢?
首先添加一个使用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);
}
现在你应该将你的动作添加到qazxsw poi数组中!请注意,我添加扩展仅用于具有重构友好过滤器。
最后但并非最不重要的是,确保将操作过滤器添加到swagger的选项中。所以将_actionWithUpload
添加到你的招摇选项并完成。
完整示例:
options.OperationFilter<FileUploadOperation>();
除了@ Nick的回答,我还要为AspNet core 2进行2次更改。
现在所有的operationIds都包含API前缀以及后缀中的Method。所以我在ActionName中静态添加了API和Post。
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>();
});
我想删除文件参数,而不是删除该操作的所有参数。
public static string GetOperationId<T>(string actionName) where T : ControllerBase => $"Api{GetControllerName<T>()}{actionName}Post";