我有一个带有Swagger 3.0的ASP.NET Core2应用程序,我想测试一下从Swagger UI上传文件的POST操作。
文件上传器控制器:
[ApiController]
public class FileUploadController : ApiControllerBase
{
private readonly IFileUploader _fileUploader;
public FileUploadController(IFileUploader fileUploader, ILogger<FileUploadController> logger) : base(logger)
{
_fileUploader = fileUploader;
}
[HttpPost]
[Route(nameof(UploadFile))]
public FileUploadResult UploadFile(IFormFile uploadedFile)
{
return _FileUploader.UploadFile(Request.Form.Files[0]);
}
}阅读Swagger文档和其他主题时,我发现我需要自定义IOperationFilter,因此我想到了以下内容:
public class FileUploadOperationFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
if (operation.OperationId.ToLower() == "apifileuploaduploadfilepost")
{
operation.Parameters.Add(new NonBodyParameter()
{
Name = "file",
In = "formData",
Description = "Upload File",
Required = true,
Type = "file"
});
operation.Consumes.Add("multipart/form-data");
}
}
}它在Swagger启动类中注册:
options.OperationFilter<FileUploadOperationFilter>();所以,所有来自IFormFile的字段都消失了,并且有一个上传文件控件,所以我可以选择"Try it out“按钮,选择一个文件,但在按下"Execute”之后,我得到以下错误:

web api本身不会崩溃,也不会抛出任何错误。我在调试过程中注意到的是-- FileUploadController的构造函数已经到达,但是FileUpload方法没有被触发。
发布于 2018-08-06 14:56:35
通过从参数中删除IFormFile uploadedFile来解决:
[HttpPost]
[Route(nameof(UploadFile))]
public FileUploadResult UploadFile()
{
return _FileUploader.UploadFile(Request.Form.Files[0]);
}发布于 2018-08-04 02:27:23
表单中的键应与方法中的参数匹配,请在筛选器中重命名:
operation.Parameters.Add(new NonBodyParameter()
{
Name = "uploadedFile",
In = "formData",
Description = "Upload File",
Required = true,
Type = "file"
});发布于 2018-12-05 18:28:17
您能否尝试此操作筛选器:
/// <summary>
/// Filter to enable handling file upload in swagger
/// </summary>
public class FormFileSwaggerFilter : IOperationFilter
{
private const string formDataMimeType = "multipart/form-data";
private static readonly string[] formFilePropertyNames =
typeof(IFormFile).GetTypeInfo().DeclaredProperties.Select(p => p.Name).ToArray();
/// <summary>
/// Applies the specified operation.
/// </summary>
/// <param name="operation">The operation.</param>
/// <param name="context">The context.</param>
public void Apply(Operation operation, OperationFilterContext context)
{
var parameters = operation.Parameters;
if (parameters == null || parameters.Count == 0) return;
var formFileParameterNames = new List<string>();
var formFileSubParameterNames = new List<string>();
ProcessActionParameters(context, ref formFileParameterNames, ref formFileSubParameterNames);
if (!formFileParameterNames.Any()) return;
var consumes = operation.Consumes;
consumes.Clear();
consumes.Add(formDataMimeType);
ProcessParameters(ref parameters, formFileSubParameterNames);
ProcessFormFileParameters(formFileParameterNames, ref parameters);
}
private static void ProcessFormFileParameters(List<string> formFileParameterNames, ref IList<IParameter> parameters)
{
foreach (var formFileParameter in formFileParameterNames)
{
parameters.Add(new NonBodyParameter()
{
Name = formFileParameter,
Type = "file",
In = "formData"
});
}
}
private static void ProcessActionParameters(OperationFilterContext context, ref List<string> formFileParameterNames,
ref List<string> formFileSubParameterNames)
{
foreach (var actionParameter in context.ApiDescription.ActionDescriptor.Parameters)
{
var properties =
actionParameter.ParameterType.GetProperties()
.Where(p => p.PropertyType == typeof(IFormFile))
.Select(p => p.Name)
.ToArray();
if (properties.Length != 0)
{
formFileParameterNames.AddRange(properties);
formFileSubParameterNames.AddRange(properties);
continue;
}
if (actionParameter.ParameterType != typeof(IFormFile)) continue;
formFileParameterNames.Add(actionParameter.Name);
}
}
private static void ProcessParameters(ref IList<IParameter> parameters, List<string> formFileSubParameterNames)
{
foreach (var parameter in parameters.ToArray())
{
if (!(parameter is NonBodyParameter) || parameter.In != "formData") continue;
if (formFileSubParameterNames.Any(p => parameter.Name.StartsWith(p + "."))
|| formFilePropertyNames.Contains(parameter.Name))
parameters.Remove(parameter);
}
}
}https://stackoverflow.com/questions/51677044
复制相似问题