VB.NEt не удается передать/загрузить zip-файл на клиент

#vb.net #download #stream #response #zipoutputstream

Вопрос:

У меня есть список строк в формате PDF со строками в виде «http://whatever.pdf» и нужно создать их zip-файл и передать его клиенту в качестве загрузки.

Странно то, что если я создам zip (я использую ZipOutputStream) и запишу файл на диск, он работает, я смогу открыть сгенерированный zip-файл и распаковать его без проблем, но если я передам его (что мне нужно сделать) Я получаю zip-файл того же размера, но который выдает ошибку при попытке его открыть.

CreateZip:

 Private Function CreateZip(pdfPathList As List(Of String), fileRoot As String) As String   Response.Clear()  Response.BufferOutput = False  Response.ContentType = "application/zip"  Response.AddHeader("content-disposition", "attachment; filename=pdf.zip")   Dim pdfPathListLocal As List(Of String) = Utility.DownloadFilesFromList(pdfPathList, fileRoot)  Dim outputMemStream = Utility.GenerateZipOutpuStream(pdfPathListLocal)  Dim zipName As String = Guid.NewGuid.ToString() amp; ".zip"  outputMemStream.Position = 0  'Utility.WriteMemoryStreamToDisk(outputMemStream, fileRoot amp; "" amp; zipName) =gt; This line creates a valid zip file on disk, but I need to avoid it.   Response.AddHeader("Content-Length", outputMemStream.Length)  Response.Write(outputMemStream) =gt; Writes the file ok in downloads, but apparently corrupted.   Return zipName  End Function  

Скачать файлы из списка:

 Public Shared Function DownloadFilesFromList(pdfPathList As List(Of String), fileRoot As String) As List(Of String)   Dim pdfPathListLocal As New List(Of String)   Dim Client As WebClient = New WebClient()  For Each strFile In pdfPathList  Dim sFile As String = Path.GetFileName(strFile)  Dim localFile As String = fileRoot   ""   sFile  Client.DownloadFile(strFile, localFile)  pdfPathListLocal.Add(localFile)  Next   Return pdfPathListLocal  End Function  

Генерировать поток вывода:

 Public Shared Function GenerateZipOutpuStream(pdfPathListLocal As List(Of String)) As MemoryStream   Dim outputMemStream = New MemoryStream()  Dim strmZipOutputStream = New ZipOutputStream(outputMemStream)  strmZipOutputStream.SetLevel(9)   Dim objCrc32 As New Crc32()   For Each strFile In pdfPathListLocal  Dim strmFile As FileStream = IO.File.OpenRead(strFile)  Dim abyBuffer(Convert.ToInt32(strmFile.Length - 1)) As Byte  strmFile.Read(abyBuffer, 0, abyBuffer.Length)   Dim sFile As String = Path.GetFileName(strFile)  Dim theEntry As ZipEntry = New ZipEntry(sFile)  theEntry.DateTime = DateTime.Now  theEntry.Size = strmFile.Length  strmFile.Close()   objCrc32.Reset()  objCrc32.Update(abyBuffer)  theEntry.Crc = objCrc32.Value   strmZipOutputStream.PutNextEntry(theEntry)  strmZipOutputStream.Write(abyBuffer, 0, abyBuffer.Length)   'IO.File.Delete(strFile)  Next   strmZipOutputStream.Finish()   Return outputMemStream  End Function  

WriteMemoryStreamToDisk:

 Public Shared Sub WriteMemoryStreamToDisk(outputMemStream As MemoryStream, file As String)   Dim buffer As Byte() = outputMemStream.ToArray()  Dim ms As New MemoryStream(buffer)  Dim newFile As New FileStream(file, FileMode.Create, FileAccess.Write)  ms.WriteTo(newFile)  newFile.Close()  ms.Close()  End Sub  

Что может быть не так? Какая-нибудь помощь?

Ответ №1:

Что я всегда делаю в первую очередь в таких случаях, так это открываю «поврежденный» файл в программе просмотра текста и выясняю, действительно ли файл предположительно (типа файла) является файлом (типа файла). Часто оказывалось, что это не так. Например, при просмотре обычного ZIP-архива первые 2 символа должны быть «PK», остальная часть файла-двоичная «тарабарщина». Аналогично для PDF-файлов: первые несколько символов «%PDF-(версия PDF)«, например «%PDF-1.7».

Особенно при загрузке, вы можете получить что-то другое, чем вы ожидаете, например, щелкнув правой кнопкой мыши ссылку на файл -gt; «Сохранить как». Оказывается, это не прямая ссылка на файл, а какой-то скрипт, который отправляет фактический файл клиенту. То, что вы получаете, когда «Сохраняете как» эту ссылку, — это вывод HTML из сценария, а не сам файл.

Существует также множество антивирусных программ, отслеживающих веб-трафик и заменяющих подозрительный файл чем-то другим.

Возможно, вы «стали жертвой» чего-то подобного.

Комментарии:

1. Спасибо за ваш ответ @Hel O’Tween. Я обнаружил, что, к моему удивлению, загруженный zip-файл (с правильным размером) содержит весь html-код aspx. Не знаю почему, но это определенно не zip-файл, но я не могу понять, почему, если я запишу файл на диск внутри webroot, он создаст действительный и рабочий zip-файл!

2. @DiegoPerez, который предполагает, что страница отображается до CreateZip вызова метода. Для загрузки лучше использовать обработчик (.ashx), а не страницу (.aspx), потому что в первом случае нет всех рамок второго.

Ответ №2:

Хорошо, поскольку я наконец нашел корень своей проблемы, я отвечу сам и надеюсь быть полезным всем, кто столкнется с той же проблемой.

Проблема заключается в том, как работает aspx «UpdatePanel», он выполняет частичную обратную передачу, что несовместимо с объектом ответа и мешает ему работать правильно.

Решение состоит в том, чтобы отключить частичную обратную передачу для конкретного элемента, вызывающего проблему, в моем случае:

Добавление этого приведет к тому, что ссылка aDownloadPdfs выполнит полную обратную передачу, и все методы объекта ответа будут работать должным образом.