【问题标题】:File Upload in WebAPIWebAPI 中的文件上传
【发布时间】:2019-02-16 09:39:12
【问题描述】:

环境

  • C# 7.2
  • .NET 核心 2.0/2.1
  • 红隼

我正在尝试通过 web api 上传文件。这似乎很简单,但我一定错过了一些微不足道的东西。

我一直在网上搜索,但没有找到完整的、可运行的示例供下载。

我已尝试插入显示如何执行此操作的 sn-ps,但无法获得完全有效的解决方案。

我创建了自己的简单测试项目。这是关键部分。

Startup.cs

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

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseStaticFiles();
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();
    }
}

值控制器

[Produces("application/json")]
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    public ValuesController() { }

    [HttpPost("upload")]
    public async Task<IActionResult> Upload(IFormFile file)
    {
        try
        {
            using (Stream strm = file?.OpenReadStream())
            {
                return Ok($"File uploaded had {file?.Length ?? -1} bytes");
            }
        }
        catch (Exception ex)
        {
            return BadRequest(ex);
        }
    }
}

如果我从邮递员那里调用这个网络方法(必须支持这个),使用:

http://localhost:5000/api/values/upload

标题: 内容类型:multipart/form-data;boundary="boundary"

身体: 带有 1 个名为“文件”的参数的表单数据,并作为文件而不是文本发送。

红隼回应:

System.IO.IOException:Stream 意外结束,内容可能已被另一个组件读取。

我也尝试了一个简单的 html 表单:

<form method="post" enctype="multipart/form-data" action="http://localhost:5000/api/values/upload">
<div>
    <p>Upload one or more files using this form:</p>
    <input type="file" name="files" />
</div>
<div>
     <input type="submit" value="Upload" />
</div>
</form>

这种做法其实是把它做成了web方法,但是IFormFile参数总是为null。

似乎邮递员正在寻找网络方法,发送数据并且多次读取流。我发现了几个对 DisableFormValueModelBinding 属性的引用,但它似乎没有帮助。我需要一个自定义属性才能使用 MS 提供的 IFormFile,这似乎很奇怪。

在表单方面,我不是为什么不发送文件的原因。

如果有人可以指点我下载的工作示例,或查看我忽略的内容,将不胜感激。

【问题讨论】:

    标签: c# asp.net-core asp.net-core-webapi


    【解决方案1】:

    您的问题涉及两个问题,其中第二个与第一个相关,这本身就是您真正关心的问题。

    1. System.IO.IOException:Stream 意外结束,内容可能已被另一个组件读取。

      这是因为您在使用 Postman 时明确设置了 Content-Type 标头(已在 cmets 中确认)。这意味着发送到您的 ASP.NET Core 端点的请求不完整,从而导致上面显示的错误。相反,只需删除此标头,让 Postman 为您处理。

    2. 这种做法其实是把它做成了web方法,但是IFormFile参数总是为null。

      这里的IFormFile实例是null只是因为HTML表单中使用的namefiles)和IFormFile参数的名称(file不匹配。您在这里需要做的就是使用例如file 在这两个位置。

    【讨论】:

      【解决方案2】:
      [HttpPost("UploadFiles")]
      public async Task<IActionResult> Post(List<IFormFile> files)
      {
          long size = files.Sum(f => f.Length);
      
          // full path to file in temp location
          var filePath = Path.GetTempFileName();
      
          foreach (var formFile in files)
          {
              if (formFile.Length > 0)
              {
                  using (var stream = new FileStream(filePath, FileMode.Create))
                  {
                      await formFile.CopyToAsync(stream);
                  }
              }
          }
      

      试试这个

      https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-2.1

          // process uploaded files
          // Don't rely on or trust the FileName property without validation.
      
          return Ok(new { count = files.Count, size, filePath});
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-06
        • 2017-07-05
        • 1970-01-01
        • 2012-11-14
        • 2020-03-27
        • 2013-11-10
        • 1970-01-01
        相关资源
        最近更新 更多