2014-12-04 11 views
7

Sunucuya dosya yüklerken harika gidiyor; hasarlı dosya yok. Ancak dosyaları indirdiğimde (salt txt: s woork) onlar büyürler ve bozulurlar. Bir çok araştırmadan sonra neyin yanlış olabileceğini bilmiyorum. Ben sadece dosyasını bir akış olarak yanıt olarak ve blob indirerek yazarım.
Herhangi bir fikir kabul edilir!AngularJS ve C# webapi kullanarak sunucudan dosya indirmeye çalışıyor

Bu iş parçacığı üzerinde yoğun bir şekilde çözüm için; Download file from an ASP.NET Web API method using AngularJS

Mevcut kod aşağıda;

WebAPI:

[Route("GetFile")] 
public HttpResponseMessage GetFile() 
{ 
    HttpResponseMessage result = null; 
    //Get file object here 
    try 
    { 
     IEnumerable<string> headerValues = Request.Headers.GetValues("fileID"); 
     int key = Int32.Parse(headerValues.FirstOrDefault()); 
     var fetchFile = db.FileRecords.Single(a => 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); 
    } 
} 

Görünüm:

<button type="button" class="btn btn-default btn-sm" data-localize="DOWNLOAD" ng-click="downloadFiles(file)"> 
    Download file 
</button> 

Denetleyici:

/******** 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; 
     }); 
} 

cevap

12

bir responsetyp olarak arraybuffer eklendi GET isteğinin e, şimdi tarayıcı dosyaları doğru yorumlar.

/******** FILE DOWNLOAD **********/ 
$scope.downloadFiles = function (file) { 
     $http({ 
      method: 'GET', 
      cache: false, 
      url: host + 'api/Files/GetFile', 
      responseType:'arraybuffer', 
      headers: { 
       'Content-Type': 'application/json; charset=utf-8', 
       'fileID': file.id 
      } 
+0

Yanıtlarınız için teşekkür ederiz, birkaç günlüğüne deniyordum ve neden indirilen dosyamın bozuk olduğunu ve orijinal olarak yüklendiğinden daha fazla bayta sahip olduğunu bulamıyordum. Çözümünü, responseType: 'arraybuffer' haricinde uyguladı. Ancak bunun büyük bir sorun olabileceğini düşünemedim. – Aamol

İlgili konular