WebAPI中的文件上传

时间:2018-09-11 20:03:17

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

环境

  • C#7.2
  • .NET core 2.0 / 2.1
  • 茶est

我正在尝试通过网络api上传文件。看起来很简单,但我必须缺少一些琐碎的东西。

我一直在搜索网络,但没有找到完整的有效示例进行下载。

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

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

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

ValuesController

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

如果我使用以下方法从邮递员(必须支持)调用此Web方法:

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

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

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

红est回应:

  

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,我需要一个自定义属性似乎很奇怪。

从形式上讲,我不是为什么不发送文件的原因。

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

2 个答案:

答案 0 :(得分:2)

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

  1.   

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

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

  2.   

    这种方法实际上使它进入了web方法,但是IFormFile参数始终为null。

    这里的IFormFile实例是null,仅仅是因为HTML格式(name中使用的filesIFormFile参数的名称({ {1}})不匹配。您在这里要做的就是使用例如在两个位置都file

答案 1 :(得分:0)

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