Почему .docx файлы повреждают при загрузке со страницы ASP.NET?

У меня есть этот после кода для подачи вложений страницы пользователю:

private void GetFile(string package, string filename)
{
    var stream = new MemoryStream();

    try
    {
        using (ZipFile zip = ZipFile.Read(package))
        {
            zip[filename].Extract(stream);
        }
    }
    catch (System.Exception ex)
    {
        throw new Exception("Resources_FileNotFound", ex);
    }

    Response.ClearContent();
    Response.ClearHeaders();
    Response.ContentType = "application/unknown";

    if (filename.EndsWith(".docx"))
    {
        Response.ContentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
    }

    Response.AddHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
    Response.BinaryWrite(stream.GetBuffer());
    stream.Dispose();
    Response.Flush();
    HttpContext.Current.ApplicationInstance.CompleteRequest();
}

Проблема состоит в том, что все поддерживаемые работы файлов правильно (jpg, gif, png, PDF, документ, и т.д.), но .docx файлы при загрузке повреждаются, и они должны быть зафиксированы Office, чтобы быть открытыми.

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

Вы знаете то, что может происходить?

25
задан Victor Rodrigues 19 March 2010 в 13:21
поделиться

3 ответа

Я тоже столкнулся с этой проблемой и нашел ответ здесь: http://www.aspmessageboard.com/showthread.php?t=230778

Оказывается, формат docx должен иметь Response.End () сразу после Response.BinaryWrite.

31
ответ дан 28 November 2019 в 21:13
поделиться

Вы не должны использовать stream.GetBuffer(), потому что он возвращает массив буфера, который может содержать неиспользуемые байты. Вместо этого используйте stream.ToArray(). Также, пробовали ли вы вызвать stream.Seek(0, SeekOrigin.Begin), прежде чем писать что-либо?

Best Regards,
Оливер Ханаппи

3
ответ дан 28 November 2019 в 21:13
поделиться

Все выглядит нормально. Моя единственная идея - попробовать вызвать Dispose в вашем потоке после вызова Response.Flush, а не до него, на всякий случай, если байты не полностью записаны перед сбросом.

0
ответ дан 28 November 2019 в 21:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: