title: Upload Attachment using Knockout.js and Ajax
body: <p>I'm having trouble getting attachments to save with my MVC 4 vb website. I am able to get a file that is a <code>media-type</code> file to send with an AJAX call to my controller, but I don't know how to use that file type to save or be converted to <code>HttpPostedFileBase</code>.</p>
  
  <p>The error I'm receiving when uploading a .docx is:</p>
  
  <pre><code>"No MediaTypeFormatter is available to read an object of type 'HttpPostedFileBase' from content with media type 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'."
  </code></pre>
  
  <p>Here is a snippet of my html code:</p>
  
  <pre><code>&lt;input id="files" name="files" class="input-file" type="file" data-bind="file: imageFile, fileObjectURL: imageObjectURL, fileBinaryData: imageBinary"&gt;
  </code></pre>
  
  <p>Here's my ko.bindinghandler:</p>
  
  <pre><code>ko.bindingHandlers.file = {
      init: function (element, valueAccessor) {
          $(element).change(function () {
              var file = this.files[0];
              if (ko.isObservable(valueAccessor())) {
                  valueAccessor()(file);
              }
          });
      },
  
      update: function (element, valueAccessor, allBindingsAccessor) {
          var file = ko.utils.unwrapObservable(valueAccessor());
          var bindings = allBindingsAccessor();
  
          if (bindings.fileObjectURL &amp;&amp; ko.isObservable(bindings.fileObjectURL)) {
              var oldUrl = bindings.fileObjectURL();
              if (oldUrl) {
                  windowURL.revokeObjectURL(oldUrl);
              }
              bindings.fileObjectURL(file &amp;&amp; windowURL.createObjectURL(file));
          }
  
          if (bindings.fileBinaryData &amp;&amp; ko.isObservable(bindings.fileBinaryData)) {
              if (!file) {
                  bindings.fileBinaryData(null);
              } else {
                  var reader = new FileReader();
                  reader.onload = function (e) {
                      bindings.fileBinaryData(e.target.result);
                  };
                  reader.readAsArrayBuffer(file);
              }
          }
      }
  };
  </code></pre>
  
  <p>Here is the AJAX call:</p>
  
  <pre><code>var fileData = monthView.imageFile();
  $.ajax({
      type: 'POST',
      url: "/api/Upload/FileUpload",
      data: fileData,
      async: false,
      cache: false,
      processData: false,
      contentType: false, 
      success: function (data) {
          console.log(data);
          imageFile(getNameFromPath(monthView.imageFile()));
      },
  });    
  </code></pre>
  
  <p>Finally here is the controller to handle the ajax call:</p>
  
  <pre><code>&lt;System.Web.Mvc.HttpPost&gt;
  Public Function FileUpload(ByVal file As HttpPostedFileBase) As Boolean
      Dim fileName As String
      Dim pathName As String
  
      If file.ContentLength &gt; 0 Then
          fileName = Path.GetFileName(file.FileName)
          pathName = Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data/uploads"), fileName)
          file.SaveAs(pathName)
          Return True
      End If
      Return False
  End Function
  </code></pre>