title: .NET Core - Web API - How to do File Upload?
body: <p>I am not able to figure out, how to write a .NET Core Web API to support File Upload. Please note I am not using ASP.NET Core MVC form for file upload but via a Servlet/JSP container.
  Here is how my <strong>project.json</strong> is defined,</p>
  
  <pre><code>{
    "dependencies": {
      "Microsoft.NETCore.App": {
        "version": "1.0.1",
        "type": "platform"
      },
      "Microsoft.AspNetCore.Mvc": "1.0.1",
      "Microsoft.AspNetCore.Routing": "1.0.1",
      "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
      "Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
      "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
      "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0",
      "Microsoft.Extensions.Configuration.Json": "1.0.0",
      "Microsoft.Extensions.Logging": "1.0.0",
      "Microsoft.Extensions.Logging.Console": "1.0.0",
      "Microsoft.Extensions.Logging.Debug": "1.0.0",
      "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
      "Npgsql": "3.1.9",
      "CoreCompat.Newtonsoft.Json": "9.0.2-beta001",
      "Newtonsoft.Json": "9.0.1"
    },
  
    "tools": {
      "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
    },
  
    "frameworks": {
      "netcoreapp1.0": {
        "imports": [
          "dotnet5.6",
          "portable-net45+win8"
        ]
      }
    },
  
    "buildOptions": {
      "emitEntryPoint": true,
      "preserveCompilationContext": true
    },
  
    "runtimeOptions": {
      "configProperties": {
        "System.GC.Server": true
      }
    },
  
    "publishOptions": {
      "include": [
        "wwwroot",
        "**/*.cshtml",
        "appsettings.json",
        "web.config"
      ]
    },
  
    "scripts": {
      "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
    }
  }
  </code></pre>
  
  <p>Here is how my <strong>Startup</strong> is defined,</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Threading.Tasks;
  using Microsoft.AspNetCore.Builder;
  using Microsoft.AspNetCore.Hosting;
  using Microsoft.Extensions.Configuration;
  using Microsoft.Extensions.DependencyInjection;
  using Microsoft.Extensions.Logging;
  
  using QCService.Models;
  
  namespace QCService
  {
      public class Startup
      {
          public Startup(IHostingEnvironment env)
          {
              var builder = new ConfigurationBuilder()
                  .SetBasePath(env.ContentRootPath)
                  .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                  .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                  .AddEnvironmentVariables();
              Configuration = builder.Build();
          }
  
          public IConfigurationRoot Configuration { get; }
  
          // This method gets called by the runtime. Use this method to add services to the container.
          public void ConfigureServices(IServiceCollection services)
          {
              // Add framework services.
              services.AddMvc();
  
              //Add SurveysRepository for Dependency Injection
              services.AddSingleton&lt;ISurveysRepository, SurveysRepository&gt;();
              //Add FeedbacksRepository for Dependency Injection
              services.AddSingleton&lt;IFeedbacksRepository, FeedbacksRepository&gt;();
              //Add AttachmentsRepository for Dependency Injection
              services.AddSingleton&lt;IAttachmentsRepository, AttachmentsRepository&gt;();
          }
  
          // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
          public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
          {
              loggerFactory.AddConsole(Configuration.GetSection("Logging"));
              loggerFactory.AddDebug();
  
              app.UseMvc();
          }
      }
  }
  </code></pre>
  
  <p>Finally here is how my <strong>Controller</strong> is defined,</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Threading.Tasks;
  using Microsoft.AspNetCore.Mvc;
  //Including model classes for Attachments
  using QCService.Models;
  using Microsoft.AspNetCore.Http;
  using Microsoft.AspNetCore.Hosting;
  using System.IO;
  using Microsoft.Net.Http.Headers;
  
  // For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
  
  namespace QCService.Controllers
  {
      [Route("api/[controller]")]
      public class AttachmentsController : Controller
      {
          public IAttachmentsRepository AttachmentItems { get; set; }
          public AttachmentsController(IAttachmentsRepository attachmentItems)
          {
              AttachmentItems = attachmentItems;
          }
  
          // GET: api/Attachments
          [HttpGet] /*http://localhost:52770/api/Attachments*/
          public IEnumerable&lt;Attachments&gt; Get()
          {
              return AttachmentItems.GetAllAttachments();
          }
  
          // GET api/Attachments/5
          [HttpGet("{id}")] /*http://localhost:52770/api/Attachments/{AttachmentID}*/
          public Attachments Get(int id)
          {
              return AttachmentItems.GetAttachment(id);
          }
  
          // GET api/Attachments/5
          [HttpGet("Feedback/{id}")] /*http://localhost:52770/api/Attachments/Feedback/{FeedbackID}*/
          public IEnumerable&lt;Attachments&gt; GetFeedbackAttachments(int id)
          {
              return AttachmentItems.GetFeedbackAttachments(id);
          }
  
          // POST api/Attachments
          [HttpPost]/*http://localhost:52770/api/Attachments/*/
          public async Task&lt;IActionResult&gt; PostFiles(ICollection&lt;IFormFile&gt; files)
          {
              try
              {
                  System.Console.WriteLine("You received the call!");
                  WriteLog("PostFiles call received!", true);
                  //We would always copy the attachments to the folder specified above but for now dump it wherver....
                  long size = files.Sum(f =&gt; f.Length);
  
                  // full path to file in temp location
                  var filePath = Path.GetTempFileName();
                  var fileName = Path.GetTempFileName();
  
                  foreach (var formFile in files)
                  {
                      if (formFile.Length &gt; 0)
                      {
                          using (var stream = new FileStream(filePath, FileMode.Create))
                          {
                              await formFile.CopyToAsync(stream);
                              //formFile.CopyToAsync(stream);
                          }
                      }
                  }
  
                  // process uploaded files
                  // Don't rely on or trust the FileName property without validation.
                  //Displaying File Name for verification purposes for now -Rohit
  
                  return Ok(new { count = files.Count, fileName, size, filePath });
              }
              catch (Exception exp)
              {
                  System.Console.WriteLine("Exception generated when uploading file - " + exp.Message);
                  WriteLog("Exception generated when uploading file - " + exp.Message, true);
                  string message = $"file / upload failed!";
                  return Json(message);
              }
          }
  
          /// &lt;summary&gt;
          /// Writes a log entry to the local file system
          /// &lt;/summary&gt;
          /// &lt;param name="Message"&gt;Message to be written to the log file&lt;/param&gt;
          /// &lt;param name="InsertNewLine"&gt;Inserts a new line&lt;/param&gt;
          public void WriteLog(string Message, bool InsertNewLine)
          {
              LogActivity ologObject = null;
              try
              {
                  string MessageString = (InsertNewLine == true ? Environment.NewLine : "") + Message;
                  if (ologObject == null)
                      ologObject = LogActivity.GetLogObject();
                  ologObject.WriteLog(Message, InsertNewLine);
              }
              catch (Exception ex)
              {
                  Console.WriteLine("Unable to write to the log file : " + ex.Message);
                  Console.WriteLine("Stack Trace : " + ex.StackTrace);
              }
          }
      }
  }
  </code></pre>
  
  <p>I have gone through this link,
  <a href="https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads" rel="noreferrer">https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads</a>
  but just can't make it work!
  Any help is appreciated!!!</p>
  
  <p>I am using the Google's Advanced Rest Client to post the data as follows,
  <a href="https://i.stack.imgur.com/uyng0.png" rel="noreferrer">This is how I am sending the POST request</a></p>
  
  <p>I keep getting response failed with following message...
  Status:
  500: Internal Server Error
  Loading time: 62 ms
  Response headers
  5
  Request headers
  2
  Redirects
  0
  Timings
  Content-Type: multipart/form-data; boundary=----WebKitFormBoundary0RKUhduCjSNZOEMN
  Content-Length: 9106
  Source message</p>
  
  <p>POST /api/Attachments HTTP/1.1
  HOST: localhost:52770
  content-type: multipart/form-data; boundary=----WebKitFormBoundary0RKUhduCjSNZOEMN
  content-length: 9106</p>
  
  <p>------WebKitFormBoundary0RKUhduCjSNZOEMN
  Content-Disposition: form-data; name="fileUpload1"; filename="1i4ymeoyov_In_the_Wild_Testing.png"
  Content-Type: image/png</p>
  
  <p>�PNG</p>
  
  <p>IHDR,I�3(tEXtSoftwareAdobe ImageReadyq�e&lt; iTXtXML:com.adobe.xmp        �8
  ^2IDATx��]  pU����@ a�H� Pe�P8 ��Ȉ��b�̌3�p�q�*�7"�h�+Yf��O�atD��(&lt;�h¦DLXdOH ������=}���}ov8_U�.....
  ------WebKitFormBoundary0RKUhduCjSNZOEMN--</p>