如何从swashbuckle的请求正文中上传多部分文件?

时间:2019-01-21 15:11:54

标签: api .net-core swashbuckle

我应该如何在.net核心中设置swashbuckle,以便可以从请求正文(多部分,禁用表单值模型绑定)上载文件?

我尝试了什么(显然在swashbuckle启动配置中添加了FileUploadHelper):

public class FileUploadHelper : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        if (operation.OperationId.ToLower() == "apifileuploadpost")
        {
            operation.Parameters.Clear();
            operation.Parameters.Add(new NonBodyParameter()
            {
                Name = "File",
                In = "formData",
                Description = "uploaded file",
                Type = "file",
                Required = true,
            });
            operation.Consumes.Add("multipart/form-data");
        }
    }
}


 [HttpPost, DisableRequestSizeLimit]
 [DisableFormValueModelBinding]      
    public async Task<IActionResult> Upload()
    {
        int id = await Request.StreamFile(fileService);
        return CreatedAtAction(nameof(GetFileInfo), id);
    }

StreamFile是一种扩展方法,该方法将请求主体中的文件内容保存在文件内容实体(byte [])中,并创建一个具有文件内容ID和一些其他信息(名称,描述等)的fileinfo实体,但仅返回生成的ID。我只希望能够大摇摇晃地单击“上传”按钮,选择文件并获取返回的ID或错误响应。我不使用IFileForm,禁用了表单值模型绑定(根据asp.net核心文档中使用流传输的大文件上传),并且该文件直接来自请求正文,因此我没有在Upload controller方法中传递任何与文件相关的参数,仅“ this HttpRequest”。这在Swashbuckle中是否可行?

1 个答案:

答案 0 :(得分:0)

您的FileUploadHelper类看起来不错。我认为问题在于OperationId是不同的。它应该是方法的名称,Upload。我根据您的情况创建了一个示例,并更改了FileUploadHelper以根据路线进行匹配,相反,我认为这更加清楚。

以下是适用于我的版本的代码段。

控制器:

[Route("api/[controller]")]
[ApiController]
public class FileUploadController : ControllerBase
{
   [HttpPost, DisableRequestSizeLimit]
   [DisableFormValueModelBinding]
   [Consumes("multipart/form-data")] // You can specify consumes here and it gets automatically added also to swagger
   public async Task<IActionResult> Upload()
   {
      int id = await Request.StreamFile(fileService);
      return CreatedAtAction(nameof(GetFileInfo), new { id = id }, null);
   }

   [HttpGet]
   [Route("{id}")]
   public async Task<IActionResult> GetFileInfo(int id)
   {
      return new JsonResult(new { id = id });
   }
}

FileUploadHelper

public class FileUploadHelper : IOperationFilter
{
   public void Apply(Operation operation, OperationFilterContext context)
   {
      if (context.ApiDescription.RelativePath == "api/FileUpload")
      {
         operation.Parameters.Clear();
         operation.Parameters.Add(new NonBodyParameter()
         {
            Name = "File",
            In = "formData",
            Description = "uploaded file",
            Type = "file",
            Required = true,
         });;
      }
   }
}

使用添加的Swagger设置启动:

public class Startup
{
   public Startup(IConfiguration configuration)
   {
      Configuration = configuration;
   }

   public IConfiguration Configuration { get; }

   // This method gets called by the runtime. Use this method to add services to the container.
   public void ConfigureServices(IServiceCollection services)
   {
      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

      services.AddSwaggerGen(c =>
      {
         c.SwaggerDoc("v1", new Info { Title = "File Upload API", Version = "v1" });
         c.OperationFilter<FileUploadHelper>();
      });
   }

   // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
   public void Configure(IApplicationBuilder app, IHostingEnvironment env)
   {
      if (env.IsDevelopment())
      {
         app.UseDeveloperExceptionPage();
      }
      else
      {
         // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
         app.UseHsts();
      }

      app.UseHttpsRedirection();
      app.UseMvc();
      app.UseSwagger();
      app.UseSwaggerUI(c =>
      {
         c.SwaggerEndpoint("/swagger/v1/swagger.json", "File Upload API");
      });
   }
}

这是用户界面中的样子。

Swashbuckle file upload