首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Swashbuckle上传文件

使用Swashbuckle上传文件
EN

Stack Overflow用户
提问于 2018-08-04 00:52:19
回答 3查看 6.4K关注 0票数 7

我有一个带有Swagger 3.0的ASP.NET Core2应用程序,我想测试一下从Swagger UI上传文件的POST操作。

文件上传器控制器:

代码语言:javascript
复制
[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,因此我想到了以下内容:

代码语言:javascript
复制
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启动类中注册:

代码语言:javascript
复制
                options.OperationFilter<FileUploadOperationFilter>();

所以,所有来自IFormFile的字段都消失了,并且有一个上传文件控件,所以我可以选择"Try it out“按钮,选择一个文件,但在按下"Execute”之后,我得到以下错误:

web api本身不会崩溃,也不会抛出任何错误。我在调试过程中注意到的是-- FileUploadController的构造函数已经到达,但是FileUpload方法没有被触发。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-08-06 14:56:35

通过从参数中删除IFormFile uploadedFile来解决:

代码语言:javascript
复制
    [HttpPost]
[Route(nameof(UploadFile))]
public FileUploadResult UploadFile()
{
    return _FileUploader.UploadFile(Request.Form.Files[0]);
}
票数 0
EN

Stack Overflow用户

发布于 2018-08-04 02:27:23

表单中的键应与方法中的参数匹配,请在筛选器中重命名:

代码语言:javascript
复制
operation.Parameters.Add(new NonBodyParameter()
            {
                Name = "uploadedFile",
                In = "formData",
                Description = "Upload File",
                Required = true,
                Type = "file"
            });
票数 0
EN

Stack Overflow用户

发布于 2018-12-05 18:28:17

您能否尝试此操作筛选器:

代码语言:javascript
复制
/// <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);
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51677044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档