Environment
- C# 7.2
- .NET core 2.0/2.1
- Kestrel
I am trying to get a file upload working thru web api. It seemed simple enough but I must be missing something trivial.
I've been searching the web, but I haven't found a full, working example to download.
I've tried plugging in the snippets showing how to do this but have not been able to get a fully working solution.
I've created my own, simple test project. Here are the key pieces.
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); } } } If I call this web method from postman (must support this) using:
http://localhost:5000/api/values/upload
Header: Content-Type: multipart/form-data;boundary="boundary"
Body: Form-Data with 1 param named 'file' and sent as a file, not text.
Kestrel responds with:
System.IO.IOException: Unexpected end of Stream, the content may have already been read by another component.
I also tried with a simple html form:
<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> This approach actually makes it into the web method, but the IFormFile parameter is always null.
It seems like postman is finding the web method, sending the data and that the stream is being read multiple times. I found several refs to an DisableFormValueModelBinding attribute, but it didn't seem to help. It seems odd that I would need a custom attribute in order to use the IFormFile that MS provides.
On the form side of things, I'm not why the file isn't being sent.
If anyone can point me to working example to download, or see what I am overlooking, it would be appreciated.