title: File Upload in WebAPI
body: <p>Environment</p>
  
  <ul>
  <li>C# 7.2</li>
  <li>.NET core 2.0/2.1</li>
  <li>Kestrel</li>
  </ul>
  
  <p>I am trying to get a file upload working thru web api. It seemed simple enough but I must be missing something trivial. </p>
  
  <p>I've been searching the web, but I haven't found a full, working example to download.</p>
  
  <p>I've tried plugging in the snippets showing how to do this but have not been able to get a fully working solution.</p>
  
  <p>I've created my own, simple test project. Here are the key pieces.</p>
  
  <p>Startup.cs</p>
  
  <pre><code>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();
      }
  }
  </code></pre>
  
  <p>ValuesController</p>
  
  <pre><code>[Produces("application/json")]
  [Route("api/[controller]")]
  [ApiController]
  public class ValuesController : ControllerBase
  {
      public ValuesController() { }
  
      [HttpPost("upload")]
      public async Task&lt;IActionResult&gt; Upload(IFormFile file)
      {
          try
          {
              using (Stream strm = file?.OpenReadStream())
              {
                  return Ok($"File uploaded had {file?.Length ?? -1} bytes");
              }
          }
          catch (Exception ex)
          {
              return BadRequest(ex);
          }
      }
  }
  </code></pre>
  
  <p>If I call this web method from postman (must support this) using:</p>
  
  <p><a href="http://localhost:5000/api/values/upload" rel="nofollow noreferrer">http://localhost:5000/api/values/upload</a></p>
  
  <p>Header:
  Content-Type: multipart/form-data;boundary="boundary"</p>
  
  <p>Body:
  Form-Data with 1 param named 'file' and sent as a file, not text.</p>
  
  <p>Kestrel responds with:</p>
  
  <blockquote>
    <p>System.IO.IOException: Unexpected end of Stream, the content may have already been read by another component.</p>
  </blockquote>
  
  <p>I also tried with a simple html form:</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;form method="post" enctype="multipart/form-data" action="http://localhost:5000/api/values/upload"&gt;
  &lt;div&gt;
      &lt;p&gt;Upload one or more files using this form:&lt;/p&gt;
      &lt;input type="file" name="files" /&gt;
  &lt;/div&gt;
  &lt;div&gt;
       &lt;input type="submit" value="Upload" /&gt;
  &lt;/div&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>This approach actually makes it into the web method, but the IFormFile parameter is always null.</p>
  
  <p>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.</p>
  
  <p>On the form side of things, I'm not why the file isn't being sent.</p>
  
  <p>If anyone can point me to working example to download, or see what I am overlooking, it would be appreciated.</p>