环境
我正在尝试通过网络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,我需要一个自定义属性似乎很奇怪。
从形式上讲,我不是为什么不发送文件的原因。
如果有人可以指出要下载的工作示例,或者看到我忽略的内容,将不胜感激。
答案 0 :(得分:2)
您的问题涉及两个问题,第二个问题仅与第一个有关,这本身就是您真正关心的问题。
System.IO.IOException:Stream意外结束,该内容可能已经被另一个组件读取。
之所以会这样,是因为您在使用Postman时明确地设置了Content-Type
标头(已在注释中确认)。这意味着发送到ASP.NET Core端点的请求不完整,从而导致上面显示的错误。相反,只需删除此标头,然后让Postman替您处理即可。
这种方法实际上使它进入了web方法,但是IFormFile参数始终为null。
这里的IFormFile
实例是null
,仅仅是因为HTML格式(name
中使用的files
和IFormFile
参数的名称({ {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});
}