5

我有一個Web API控制器,它看起來像這樣:如何使用ASP.net Web API和Javascript下載二進制文件?

using System; 
using System.Net; 
using System.Net.Http; 
using System.Net.Http.Headers; 
using System.Web.Http; 
using System.Threading.Tasks; 
using System.IO; 

    namespace APIIntegration.Controllers 
    { 
     public class TestController : ApiController 
     { 
      // http://localhost/api/test 
      [HttpGet]   
      public async Task<HttpResponseMessage> Get() 
      { 
       Stream stream = streamWith256Bytes;    
       HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);    
       result.Content = new StreamContent(stream); 
       result.Content.Headers.ContentLength = stream.Length;    
       result.Content.Headers.ContentType = 
        new MediaTypeHeaderValue("application/octet-stream"); 
       result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment"); 
       result.Content.Headers.ContentDisposition.FileName = "foo.bin"; 
       return result; 
      } 

      private static Stream streamWith256Bytes 
      { 
       get 
       { 
        MemoryStream stream = new MemoryStream(); 
        for (int i = 0; i <256 ; i++) 
        { 
         stream.WriteByte(Convert.ToByte(i)); 
        } 
        stream.Position = 0; 
        return stream; 
       } 
      } 
     } 
    } 

總之,該控制器會嘗試一個256字節的文件下載到瀏覽器。起初,它似乎工作,但是當檢查下載的文件時,大小是512字節而不是預期的256字節,並且不可打印的字符被丟棄。

如何修改此代碼以便可以正確下載二進制數據?

編輯:我還要提到的是我看到了類似的問題在這裏:Problems with downloading pdf file from web api service其中問題得到了解決通過添加Content-Length頭,但是這並沒有解決這個問題對我來說。

編輯:我修改了上面的源代碼,給出了一個完整的,如何重現的工作示例。

編輯:我發現上面的代碼實際上正確地工作,當我在地址欄中鍵入地址,但是當使用JavaScript來啓動下載時,這就是我遇到問題的地方。

+0

我認爲這可能是MemoryStream的是如何工作的細微差別。嘗試填充正常的Byte []並用它構造MemoryStream,而不是直接寫入空實例。 – Machinarius

回答

4

我找到了解決辦法。在我的Javascript中,我使用Angular來使用Angular $ http服務啓動文件下載。默認情況下,此服務將響應解釋爲文本。我不得不告訴Angular將響應解釋爲一個blob,並且解決了所有問題。

我工作的代碼如下所示:

function download(downloadUrl) { 
    $http({ 
     url: downloadUrl, 
     responseType: "blob" 
    }) 
    .then(function (response) { 
     var blob = new Blob([response.data], { type: "application/octet-stream" }); 
     saveAs(blob, "foo.bin"); 
    }, function (response) { 
     alert("error downloading file from " + downloadUrl); 
    }); 
} 
+0

responseType:「blob」!!!! – Pascal

相關問題