views:

522

answers:

3

I have this following code for bringing page attachments to the user:

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();
}

The problem is that all supported files works properly (jpg, gif, png, pdf, doc, etc), but .docx files, when downloaded, are corrupted and they need to be fixed by Office in order to be opened.

At first I didn't know if the problem was at uncompressing the zip file that contained the .docx, so instead of putting the output file only in the response, I saved it first, and the file opened successfully, so I know the problem should be at response writing.

Do you know what can be happening?

A: 

It all looks ok. My only idea is to try calling Dispose on your stream after calling Response.Flush instead of before, just in case the bytes aren't entirely written before flushing.

Ray
I did this also, without success.
Victor Rodrigues
just taking a wild-ass guess here... try it using content type "application/octet-stream" and see if you get a valid file downloaded. btw - this is probably more appropriate than "application/unknown" when you don't know the file type.
Ray
+1  A: 

You should not use stream.GetBuffer() because it returns the buffer array which might contain unused bytes. Use stream.ToArray() instead. Also, have you tried calling stream.Seek(0, SeekOrigin.Begin) before writing anything?

Best Regards,
Oliver Hanappi

Oliver Hanappi
I did these things, but neither did resolve the problem =/
Victor Rodrigues
+1  A: 

I also ran into this problem and actually found the answer here: http://www.aspmessageboard.com/showthread.php?t=230778

It turns out that the docx format needs to have Response.End() right after the Response.BinaryWrite.

Geoff Tanaka