5

Mam kontroler sieci Web API, które wygląda tak:Jak pobrać plik binarny za pomocą interfejsu ASP.net Web API i 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; 
       } 
      } 
     } 
    } 

w skrócie, to regulator próbuje pobrać plik 256 bajtów do przeglądarki. Na początku wygląda na to, że działa, ale po pobraniu pobranego pliku rozmiar wynosi 512 bajtów zamiast oczekiwanych 256 bajtów, a niedrukowalne znaki są niszczone.

Jak mogę zmodyfikować ten kod, aby dane binarne mogły zostać pobrane poprawnie?

Edit: Powinienem również wspomnieć, że widziałem tu podobne pytanie: Problems with downloading pdf file from web api service gdy problem został rozwiązany przez dodanie nagłówka Content-Length, ale to nie rozwiązuje to dla mnie.

Edytuj: Zmodyfikowałem powyższy kod źródłowy, aby uzyskać pełny, działający przykład odtwarzania.

Edit: odkryłem, że powyższy kod faktycznie działa poprawnie kiedy wprowadź adres w pasku adresu, ale gdy przy użyciu JavaScript, aby rozpocząć pobieranie, to gdzie mam problem.

+0

myślę, że może to być niuans jak MemoryStream działa. Spróbuj wypełnić normalny bajt [] i skonstruuj MemoryStream, zamiast wpisywać go bezpośrednio do pustej instancji. – Machinarius

Odpowiedz

4

Znalazłem rozwiązanie. W moim Javascriptu użyłem Angular, aby zainicjować pobieranie pliku przy użyciu usługi Angular $ http. Domyślnie ta usługa interpretuje odpowiedź jako tekst. Musiałem powiedzieć Angularowi, by interpretował odpowiedź jako blob, i to naprawiło wszystko.

Mój kod pracy wygląda następująco:

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

Powiązane problemy