РЕДАКТИРОВАТЬ - РЕШЕНО: разница заключалась в том, что в «основном» случае загрузка была инициирована с помощью цикла обратного вызова, а в «тестовом» случае она была инициирована с помощью функции нажатия кнопки на стороне сервера. Я предполагаю, что запрос на загрузку и цикл обратного вызова мешали друг другу, останавливая загрузку и вызывая неактивность страницы (как описано ниже). Когда я перенастроил загрузку на главной странице, чтобы она начиналась с отправки вместо обратного вызова, она инициировала загрузку.
Это в VS2013 Ultimate, Win7Pro, VB.Net, веб-сайтах (не проектах), IISExpress.
Я создал тестовый сайт для разработки функций для создания потоков памяти OpenXML PPTX и XLSX, а также их архивирования и загрузки с помощью DotNetZip. Получил, чтобы он работал нормально. Затем я объединил весь этот код со своим «основным» сайтом. Оба сайта находятся на одном компьютере; Я могу запустить тестовый сайт и основной сайт одновременно. Обработка основного сайта несколько сложнее, но только с точки зрения доступа и скачивания большего количества файлов.
Тем не менее, функция Zip and Download (ниже) отлично работает на тестовом сайте, но точно такой же код не работает на основном сайте (с запущенным тестовым сайтом или без него).
В функции Zip.Save есть ловушка для ошибок (см. ниже), где загрузка происходит, но ошибка не появляется.
Такое же общее поведение в Chrome, Firefox и IE11.
Одна особенность, которая может быть ключом к разгадке, заключается в том, что когда загрузка с основного сайта завершается неудачно, функциональность на стороне сервера «выходит из строя». Локальные функции JS работают, но приложение не отвечает на обратные вызовы. Когда я нажимаю F5 в браузере, он снова работает.
Я обновил пакет DotNetZip на основном сайте. Объект Zip работает правильно, так как выдает ошибку при повторяющихся именах файлов.
Я думал, что это может быть функция загрузки, как написано, однако на тестовом сайте она работает. Кроме того, другая часть основного сайта выполняет незаархивированную загрузку потока памяти (включена как второй блок кода ниже), и это работает нормально.
Я думал, что это могут быть данные. Поэтому я заблокировал основной сайт, чтобы получить доступ, преобразовать его в поток памяти и загрузить тот же файл, к которому обращаются и который загружается на тестовом сайте. Тем не менее загрузка с основного сайта не работает.
Когда я сравниваю контрольные значения объекта Zip на двух сайтах, они выглядят одинаково. Длина wrkFS.ContentStream одинакова в обоих случаях. Имена файлов разные, однако это: Test_2EFVG1THK5.xlsx (основной) 6-18_12-46-28_0.xlsx (тестовый), которые являются допустимыми именами файлов.
РЕДАКТИРОВАТЬ: я сохранил zip-файл на диск из основной программы, вместо того, чтобы пытаться загрузить его, используя это:
wrkFilePath = "D:\filepath\test.zip"
wrkZip.Save(wrkFilePath)
И это работало нормально. Так что это, возможно, изолирует проблему от этого утверждения
wrkZip.Save(context.Response.OutputStream)
РЕДАКТИРОВАТЬ: основываясь на помощи, которую я получил здесь:
Преобразовать DotNetZip ZipFile в байтовый массив
Я использовал эту конструкцию:
Dim ms as New MemoryStream
wrkZip.Save(ms)
wrkBytes = ms.ToArray()
context.Response.BinaryWrite(wrkByteAr)
чтобы обойти ZipFile.Save(в контексте), и это тоже не сработало; нет загрузки, нет сообщения об ошибке, и страница не работает. Однако, по крайней мере, теперь я могу предположить, что это не проблема с ZipFile.Save.
На данный момент я не могу диагностировать проблему.
Мы ценим любые предложения.
Вот код, который работает на тестовом сайте, но не на основном сайте.
Public Sub ZipAndDownloadMemoryStreams(ByVal context As HttpContext) _
Implements IHttpHandler.ProcessRequest
Dim rtn As String = ""
Try
Dim wrkAr As ArrayList
wrkAr = SC.ContentArrayForDownLoad
If wrkAr.Count = 0 Then
Dim wrkStop As Integer = 0
Exit Sub
End If
Dim wrkFS As ZipDownloadContentPair
Using wrkZip As New ZipFile
'----- create zip, add memory stream----------
For n As Integer = 0 To wrkAr.Count - 1
wrkFS = wrkAr(n)
wrkZip.AddEntry(wrkFS.FileName, wrkFS.ContentStream)
Next
context.Response.Clear()
context.Response.ContentType = "application/force-download"
context.Response.AddHeader( _
"content-disposition", _
"attachment; filename=" & "_XYZ_Export.zip")
'---- save context (initiate download)-----
wrkZip.Save(context.Response.OutputStream)
wrkZip.Dispose()
End Using
Catch ex As Exception
Dim exmsg As String = ex.Message
Dim wrkStop As String = ""
End Try
End Sub
Ниже приведена функция загрузки без архива, которая отлично работает на основном сайте. Возможно, можно преобразовать содержимое Zip в массив байтов и попробовать загрузить таким образом, однако я не уверен, как это сработает.
(СМ. РЕДАКТИРОВАТЬ ЗАМЕЧАНИЕ ВЫШЕ --- Я реализовал версию ниже, т.е. попытался загрузить массив байтов вместо прямого ZipFile.Save(), однако это не помогло, все еще не загружается и все еще не дать любое сообщение об ошибке)
Public Sub DownloadEncryptedMemoryStream(ByVal context As HttpContext) _
Implements IHttpHandler.ProcessRequest
Dim wrkMemoryStream As New System.IO.MemoryStream()
wrkMemoryStream = SC.ContentForDownload
Dim wrkFileName As String = SC.ExportEncryptedFileName
wrkMemoryStream.Position = 0
Dim wrkBytesInStream As Byte() = New Byte(wrkMemoryStream.Length - 1) {}
wrkMemoryStream.Read(wrkBytesInStream, 0, CInt(wrkMemoryStream.Length))
Dim wrkStr As String = ""
wrkStr = Encoding.UTF8.GetString(wrkMemoryStream.ToArray())
wrkMemoryStream.Close()
context.Response.Clear()
context.Response.ContentType = "application/force-download"
context.Response.AddHeader("content-disposition", "attachment; filename=" & wrkFileName)
context.Response.BinaryWrite(wrkBytesInStream)
wrkBytesInStream = Nothing
context.Response.End()