Загрузка DotNetZip работает на одном сайте, а не на другом

РЕДАКТИРОВАТЬ - РЕШЕНО: разница заключалась в том, что в «основном» случае загрузка была инициирована с помощью цикла обратного вызова, а в «тестовом» случае она была инициирована с помощью функции нажатия кнопки на стороне сервера. Я предполагаю, что запрос на загрузку и цикл обратного вызова мешали друг другу, останавливая загрузку и вызывая неактивность страницы (как описано ниже). Когда я перенастроил загрузку на главной странице, чтобы она начиналась с отправки вместо обратного вызова, она инициировала загрузку.

Это в 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()

person wayfarer    schedule 18.06.2015    source источник


Ответы (1)


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

person wayfarer    schedule 20.06.2015