title: Web API: Upload files via Ajax post
body: <p>I have this following snippet for uploading files via Ajax post (using Knockout js library)</p>
  
  <pre><code>ko.bindingHandlers.fileUpload = {
  init: function (element, valueAccessor) {
      $(element).after('&lt;div class="progress"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;div class="percent"&gt;0%&lt;/div&gt;&lt;/div&gt;&lt;div class="progressError"&gt;&lt;/div&gt;');
  },
  update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
  
      var options = ko.utils.unwrapObservable(valueAccessor()),
          property = ko.utils.unwrapObservable(options.property),
          url = ko.utils.unwrapObservable(options.url);
  
      if (property &amp;&amp; url) {
  
          $(element).change(function () {
              if (element.files.length) {
                  var $this = $(this),
                      fileName = $this.val();
                  alert(fileName);
                  // this uses jquery.form.js plugin
                  $(element.form).ajaxSubmit({
                      url: url, //WEB API URL
                      type: "POST",
                      dataType: "text", //I want to upload .doc / excell files
                      headers: { "Content-Disposition": "attachment; filename=" + fileName },
                      beforeSubmit: function () {
                          $(".progress").show();
                          $(".progressError").hide();
                          $(".bar").width("0%")
                          $(".percent").html("0%");
                      },
                      uploadProgress: function (event, position, total, percentComplete) {
                          var percentVal = percentComplete + "%";
                          $(".bar").width(percentVal)
                          $(".percent").html(percentVal);
                      },
                      success: function (data) {
                          $(".progress").hide();
                          $(".progressError").hide();
                          // set viewModel property to filename
                          bindingContext.$data[property](data);
                      },
                      error: function (jqXHR, textStatus, errorThrown) {
                          $(".progress").hide();
                          $("div.progressError").html(jqXHR.responseText);
                      }
                  });
              }
          });
      }
  }
  </code></pre>
  
  <p>}</p>
  
  <p>now my problem is creating the WEB API for this. </p>
  
  <pre><code>$(element.form).ajaxSubmit({
      url: url, //WEB API URL
      type: "POST",
      dataType: "text", //I want to upload .doc / excell files
      headers: { "Content-Disposition": "attachment; filename=" + fileName },
  </code></pre>
  
  <p>I want to upload Word/Excell document. Can someone give me an idea how to get this done in ASP.NET WEB API?</p>
  
  <p>UPDATE:</p>
  
  <p>I finally made an WEB API for this</p>
  
  <pre><code>  public class UploadController : ApiController
  {
  
      public async Task&lt;HttpResponseMessage&gt; PostFormData()
      {
          // Check if the request contains multipart/form-data.
          if (!Request.Content.IsMimeMultipartContent())
          {
              throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
          }
  
          string root = HttpContext.Current.Server.MapPath("~/App_Data");
          var provider = new MultipartFormDataStreamProvider(root);
          try
          {
              // Read the form data.
              await Request.Content.ReadAsMultipartAsync(provider);
  
              // This illustrates how to get the file names.
              foreach (MultipartFileData file in provider.FileData)
              {
                  Trace.WriteLine(file.Headers.ContentDisposition.FileName);
                  Trace.WriteLine("Server file path: " + file.LocalFileName);
              }
              return Request.CreateResponse(HttpStatusCode.OK);
  
              //return new HttpResponseMessage()
              //{
              //    Content = new StringContent("File uploaded.")
              //};
  
          }
          catch (System.Exception e)
          {
              return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, e);
          }
      }
  </code></pre>
  
  <p>It works ok (data successfully uploaded) but the problem is, it seems like in doesnt hit this section after the data is succesfully uploaded.</p>
  
  <pre><code>  success: function (data) {
                          $(".progress").hide();
                          $(".progressError").hide();
                          // set viewModel property to filename
                          bindingContext.$data[property](data);
                      },
  </code></pre>
  
  <p>I have to inform the client of what the status of the upload.</p>