title: Uploading a file using AJAX to ASMX service
body: <p>I have been having an issue trying to upload files to an existing ASMX service that we have (see C# below).  We currently have a Silverlight app which uses the service without any issues, but I have not been successful in getting our new app which uses AJAX to leverage the service.</p>
  
  <p>I have pulled advice from these in for reference for much of this:</p>
  
  <ul>
  <li><p><a href="https://stackoverflow.com/questions/17845032/net-mvc-deserialize-byte-array-from-json-uint8array">.NET MVC deserialize byte array from JSON Uint8Array</a></p></li>
  <li><p><a href="https://stackoverflow.com/questions/9267899/arraybuffer-to-base64-encoded-string">ArrayBuffer to base64 encoded string</a></p></li>
  </ul>
  
  <p>Have an  of type="file" which triggers this function:</p>
  
  <pre><code>function ArrayBufferToBase64(buffer) {
      var binary = '';
      var bytes = new Uint8Array(buffer);
  
      for (var xx = 0, len = bytes.byteLength; xx &lt; len; ++xx) {
          binary += String.fromCharCode(bytes[xx]);
      }
      return window.btoa(binary);
  
      // return btoa(String.fromCharCode.apply(null, bytes)); // Note: tried this but always get an error "Maximum call stack size exceeded"
  }
  
  function DoUpload(files) {
      var reader = new FileReader();
      reader.onload = function (e) {
          var data = {
              file: ArrayBufferToBase64(e.target.result),
              extension: file.name.substr(file.name.lastIndexOf("."))
          };
  
          $.ajax({
              headers: {
                  "X-RequestDigest": $("#__REQUESTDIGEST").val()
              },
              url: "{baseurl}" + "FileInfo.asmx/UploadFile",
              contentType: "application/json",
              data: JSON.stringify(data),
              dataType: 'json',
              type: "POST",
              success: function (response: ITempDocumentInfo) {
                  dfd.resolve();
              },
              error: function (e) {
                  console.error(e);
              }
          });
      };
      reader.readAsArrayBuffer(file);
  }
  </code></pre>
  
  <p>The service lives in SharePoint and looks like this:</p>
  
  <pre><code>[WebService(Namespace = "http://www.blah.com/")]
  [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  [System.ComponentModel.ToolboxItem(false)]
  [System.Web.Script.Services.ScriptService]
  public class FileInfo : System.Web.Services.WebService
  {
      [WebMethod(EnableSession = true)]
      public TempDocumentInfo AddScannedItem(string instanceId, string uri, string itemKey, string data, string extension)
      {
          byte[] bytes = new byte[data.Length * sizeof(char)];
          System.Buffer.BlockCopy(data.ToCharArray(), 0, bytes, 0, bytes.Length);
          var stream = new MemoryStream(bytes);
          .
          .
          .
      }
  }
  </code></pre>
  
  <p>Once I have the data in C#, I cannot seem to be able to be able to do anything with it.  For example.  Uploading and processing a bmp image throws an exception:</p>
  
  <pre><code>var blah = System.Windows
                   .Media
                   .Imaging
                   .BmpBitmapDecoder
                   .Create(stream,
                           BitmapCreateOptions.PreservePixelFormat,            
                           BitmapCacheOption.None);
  </code></pre>
  
  <p>Am I not generating the AJAX request correctly?</p>