WebAPI 中的文件上传

Ste*_* R. 4 c# asp.net-core asp.net-core-webapi

环境

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

我正在尝试通过 web api 进行文件上传。这看起来很简单,但我一定遗漏了一些微不足道的东西。

我一直在网上搜索,但我还没有找到一个完整的、有效的例子来下载。

我已经尝试插入显示如何执行此操作的代码段,但无法获得完整的解决方案。

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

启动文件

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

值控制器

[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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

红隼回应:

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

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这种方法实际上使其成为了 web 方法,但 IFormFile 参数始终为 null。

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

在形式方面,我不明白为什么文件没有被发送。

如果有人可以指出我要下载的工作示例,或者看看我忽略了什么,将不胜感激。

Kir*_*kin 5

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

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

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

  2. 这种方法实际上使其成为了 web 方法,但 IFormFile 参数始终为 null。

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