2

Я пытаюсь вернуть файл в ASP.NET Web API Controller. Этот файл представляет собой динамически созданный PDF-файл, сохраненный в MemoryStream.Угловой/Web API 2 возвращает недопустимый или поврежденный файл с StreamContent или ByteArrayContent

Клиент (браузер) получает файл успешно, но когда я открываю файл, я вижу, что все страницы полностью пусты.

Дело в том, что если я возьму тот же MemoryStream и напишу его в файл, этот файл будет отображаться правильно, поэтому я предполагаю, что проблема связана с передачей файлов через Интернет.

Мой контроллер выглядит следующим образом:

[HttpGet][Route("export/pdf")] 
public HttpResponseMessage ExportAsPdf() 
{ 
    MemoryStream memStream = new MemoryStream(); 
    PdfExporter.Instance.Generate(memStream); 

    memStream.Position = 0; 
    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK); 
    result.Content = new ByteArrayContent(memStream.ToArray()); //OR: new StreamContent(memStream); 
    return result; 
} 

Просто попробовать, если я пишу поток на диск, она отображается правильно:

[HttpGet][Route("export/pdf")] 
public HttpResponseMessage ExportAsPdf() 
{ 
    MemoryStream memStream = new MemoryStream(); 
    PdfExporter.Instance.Generate(memStream); 

    memStream.Position = 0; 
    using (var fs = new FileStream("C:\\Temp\\test.pdf", FileMode.OpenOrCreate, FileAccess.ReadWrite)) 
    { 
     memStream.CopyTo(fs); 
    } 

    return null; 
} 

Отличия:

  • PDF сохранен на диске: 34KB
  • PDF, переданный через Интернет : 60KB

Если сравнивать оба файл содержимого, основные отличия (!):

File Differences

Слева Ф передаются через сеть; справа, PDF сохранен на диске.

С кодом нет в коде? Возможно, что-то связано с кодировками?

Спасибо!

ответ

2

Ну, он оказался клиент (браузер) проблема, а не проблема с сервером. Я использую AngularJS в интерфейсе, поэтому, когда была получена реакция, Angular автоматически преобразует ее в строку Javascript. В этом преобразовании двоичного содержимое файла были как-то изменено ...

В основном это было решено, говоря Угловой не преобразовывать ответ в строку:

$http.get(url, { responseType: 'arraybuffer' }) 
.then(function(response) { 
    var dataBlob = new Blob([response.data], { type: 'application/pdf'}); 
    FileSaver.saveAs(dataBlob, 'myFile.pdf'); 
}); 

А затем сохранить ответ в виде файл, которому помогает услуга Angular File Saver.

2

I Гесс вы должны установить ContentDisposition и ContentType вроде этого:

[HttpGet][Route("export/pdf")] 
public HttpResponseMessage ExportAsPdf() 
{ 
    MemoryStream memStream = new MemoryStream(); 
    PdfExporter.Instance.Generate(memStream); 

    var result = new HttpResponseMessage(HttpStatusCode.OK) 
    { 
     Content = new ByteArrayContent(memStream.ToArray()) 
    }; 
    result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") 
    { 
     FileName = "YourName.pdf" 
    }; 
    result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
    return result; 
} 
+0

Вы избили меня до него. :) так близко. за вас. – Nkosi

+0

Извините, но не повезло :(То же самое: кое-что указать: 'memStream.GetBuffer()' возвращает массив байтов размером ~ 64 Кбайт, а 'memStream.ToArray()' возвращает массив байтов ~ 34K ... – Adrian

+2

Не использовать GetBuffer(), поскольку он возвращает массив фиксированного размера ... использовать ToArray(). –

0

Попробуйте

[HttpGet][Route("export/pdf")] 
public HttpResponseMessage ExportAsPdf() 
{ 
    MemoryStream memStream = new MemoryStream(); 
    PdfExporter.Instance.Generate(memStream); 

    //get buffer 
    var buffer = memStream.GetBuffer(); 
    //content length for header 
    var contentLength = buffer.Length; 

    var statuscode = HttpStatusCode.OK; 
    var response = Request.CreateResponse(statuscode); 
    response.Content = new StreamContent(new MemoryStream(buffer)); 
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf"); 
    response.Content.Headers.ContentLength = contentLength; 
    ContentDispositionHeaderValue contentDisposition = null; 
    if (ContentDispositionHeaderValue.TryParse("inline; filename=my_filename.pdf", out contentDisposition)) { 
     response.Content.Headers.ContentDisposition = contentDisposition; 
    } 

    return response; 
} 
+0

К сожалению, тот же результат ... как будто ничего не изменилось. – Adrian

 Смежные вопросы

  • Нет связанных вопросов^_^