title: Trying to download file from server using angularJS and c# webapi
body: <p>When uploading files to the server it goes great; no damaged files. However when i download files ( other than pure txt:s they woork)
  they grow in size and become corrupt. After alot of investigation I dont know what could be wrong. Im simply writing the file 
  as a stream to the response and downloading the blob.<br>
  Any ideas are welcome!</p>
  
  <p>Relied heavily on this Thread for the solution ; <a href="https://stackoverflow.com/questions/24080018/download-file-from-a-webapi-method-using-angularjs">Download file from an ASP.NET Web API method using AngularJS</a></p>
  
  <p>Current Code below; </p>
  
  <p><strong>WebApi:</strong></p>
  
  <pre><code>    [Route("GetFile")]
  public HttpResponseMessage GetFile()
  {
      HttpResponseMessage result = null;
      //Get file object here
      try 
      {
          IEnumerable&lt;string&gt; headerValues = Request.Headers.GetValues("fileID");
          int key = Int32.Parse(headerValues.FirstOrDefault());
          var fetchFile = db.FileRecords.Single(a =&gt; a.id == key);
  
          var localFilePath = fetchFile.path + fetchFile.name;
  
          if (!System.IO.File.Exists(localFilePath))
          {
              result = Request.CreateResponse(HttpStatusCode.Gone);
          }
          else
          {// serve the file to the client
              //I have used the x-filename header to send the filename. This is a custom header for convenience.
              //You should set the content-type mime header for your response too, so the browser knows the data format.
              var info = System.IO.File.GetAttributes(localFilePath);
              result = Request.CreateResponse(HttpStatusCode.OK);
              result.Content = new StreamContent(new FileStream(localFilePath, FileMode.Open, FileAccess.Read));
              result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
              result.Content.Headers.Add("x-filename", fetchFile.name);
              result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
              result.Content.Headers.ContentDisposition.FileName = fetchFile.name;
          }
          return result;
      }
      catch (Exception e)
      {
          return Request.CreateResponse(HttpStatusCode.BadRequest);
      }
  }
  </code></pre>
  
  <p><strong>View:</strong></p>
  
  <pre><code>&lt;button type="button" class="btn btn-default btn-sm" data-localize="DOWNLOAD" ng-click="downloadFiles(file)"&gt;
      Download file
  &lt;/button&gt;
  </code></pre>
  
  <p><strong>Controller:</strong></p>
  
  <pre><code>    /******** FILE DOWNLOAD  **********/
  $scope.downloadFiles = function (file) {
          $http({
              method: 'GET',
              cache: false,
              url: host + 'api/Files/GetFile',
              headers: {
                  'Content-Type': 'application/json; charset=utf-8',
                  'fileID': file.id
              }
          }).success(function (data, status, headers) {
              var octetStreamMime = 'application/octet-stream';
              var success = false;
  
              // Get the headers
              headers = headers();
  
              // Get the filename from the x-filename header or default to "download.bin"
              var filename = headers['x-filename'] || 'download.bin';
  
              // Determine the content type from the header or default to "application/octet-stream"
              var contentType = headers['content-type'] || octetStreamMime;
  
              try {
  
                  console.log(filename);
                  // Try using msSaveBlob if supported
                  console.log("Trying saveBlob method ...");
                  var blob = new Blob([data], { type: contentType });
                  if (navigator.msSaveBlob)
                      navigator.msSaveBlob(blob, filename);
                  else {
                      // Try using other saveBlob implementations, if available
                      var saveBlob = navigator.webkitSaveBlob || navigator.mozSaveBlob || navigator.saveBlob;
                      if (saveBlob === undefined) throw "Not supported";
                      saveBlob(blob, filename);
                  }
                  console.log("saveBlob succeeded");
                  success = true;
              } catch (ex) {
                  console.log("saveBlob method failed with the following exception:");
                  console.log(ex);
              }
  
              if (!success) {
                  // Get the blob url creator
                  var urlCreator = window.URL || window.webkitURL || window.mozURL || window.msURL;
                  if (urlCreator) {
                      // Try to use a download link
                      var link = document.createElement('a');
                      if ('download' in link) {
                          // Try to simulate a click
                          try {
                              // Prepare a blob URL
                              console.log("Trying download link method with simulated click ...");
                              var blob = new Blob([data], { type: contentType });
                              var url = urlCreator.createObjectURL(blob);
                              link.setAttribute('href', url);
  
                              // Set the download attribute (Supported in Chrome 14+ / Firefox 20+)
                              link.setAttribute("download", filename);
  
                              // Simulate clicking the download link
                              var event = document.createEvent('MouseEvents');
                              event.initMouseEvent('click', true, true, window, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
                              link.dispatchEvent(event);
                              console.log("Download link method with simulated click succeeded");
                              success = true;
  
                          } catch (ex) {
                              console.log("Download link method with simulated click failed with the following exception:");
                              console.log(ex);
                          }
                      }
  
                      if (!success) {
                          // Fallback to window.location method
                          try {
                              // Prepare a blob URL
                              // Use application/octet-stream when using window.location to force download
                              console.log("Trying download link method with window.location ...");
                              var blob = new Blob([data], { type: octetStreamMime });
                              var url = urlCreator.createObjectURL(blob);
                              window.location = url;
                              console.log("Download link method with window.location succeeded");
                              success = true;
                          } catch (ex) {
                              console.log("Download link method with window.location failed with the following exception:");
                              console.log(ex);
                          }
                      }
  
                  }
              }
  
              if (!success) {
                  // Fallback to window.open method
                  console.log("No methods worked for saving the arraybuffer, using last resort window.open");
                  window.open(httpPath, '_blank', '');
              }
              /******************/
  
  
          }).error(function (data, status) {
  
              console.log("Request failed with status: " + status);
  
              // Optionally write the error out to scope
              //$scope.errorDetails = "Request failed with status: " + status;
          });
  }
  </code></pre>