【问题标题】:Upload a file on with Swashbuckle Swagger使用 Swashbuckle Swagger 上传文件
【发布时间】:2018-08-03 16:52:18
【问题描述】:

我有一个带有 Swagger 3.0 的 ASP.NET Core 2 应用程序,我想通过 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 中的所有字段都消失了,取而代之的是上传文件控件,所以我可以选择“试用”按钮,选择一个文件,但在按下“执行”后,我收到以下错误:

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

【问题讨论】:

    标签: c# asp.net-core swagger


    【解决方案1】:

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

    operation.Parameters.Add(new NonBodyParameter()
                {
                    Name = "uploadedFile",
                    In = "formData",
                    Description = "Upload File",
                    Required = true,
                    Type = "file"
                });
    

    【讨论】:

      【解决方案2】:

      从参数中去掉IFormFile uploadFile解决:

          [HttpPost]
      [Route(nameof(UploadFile))]
      public FileUploadResult UploadFile()
      {
          return _FileUploader.UploadFile(Request.Form.Files[0]);
      }
      

      【讨论】:

        【解决方案3】:

        你能试试这个操作过滤器吗:

        /// <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);
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2021-04-13
          • 2018-07-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-26
          • 1970-01-01
          • 2020-10-30
          相关资源
          最近更新 更多