2014-12-04 12 views
7

Khi tải tệp lên máy chủ, nó sẽ trở nên tuyệt vời; không có tệp bị hỏng. Tuy nhiên khi tôi tải xuống các tệp (khác với txt thuần túy: chúng sẽ woork) chúng phát triển về kích thước và trở nên bị hỏng. Sau nhiều lần điều tra, tôi không biết điều gì có thể sai. Im chỉ cần viết tệp làm luồng cho phản hồi và tải xuống blob.
Bất kỳ ý tưởng nào đều được hoan nghênh!Cố gắng tải xuống tệp từ máy chủ bằng angularJS và C# webapi

Dựa chủ yếu vào Chủ đề này cho giải pháp; Download file from an ASP.NET Web API method using AngularJS

Mã hiện tại bên dưới;

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

Xem:

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

Bộ điều khiển:

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

Trả lời

12

Thêm arraybuffer như một responsetyp e của yêu cầu GET, bây giờ trình duyệt diễn giải chính xác các tệp.

/******** 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

Cảm ơn câu trả lời, tôi đã thử vài ngày và không thể tìm thấy lý do tệp tải xuống của tôi bị hỏng và có nhiều byte hơn so với tải lên ban đầu. Tôi đã triển khai giải pháp giống như của bạn ngoại trừ responseType: 'arraybuffer'. Nhưng không thể nghĩ đây có thể là vấn đề lớn. – Aamol

Các vấn đề liên quan