0

Let me start off by saying I'm sure this is something that's quite simple, unfortunately I just can't seem to figure it out. So here's my problem, I query the database, return what I need, zip it all up, and prompt user to save. When You attempt to open this, there are no files inside the folder. Where has my data gone? I stepped through everything, and it appears to write everything properly. Any help would be greatly appreciated!!

if (e.CommandName == "DownloadAttachment")
    {
        e.Canceled = true;
        // Create a zip and send it to the client.
        //Response.Write(@"<script language='javascript'>alert('Details saved successfully')</script>");
        var item = e.Item as GridEditableItem;
        fileId = (int)item.GetDataKeyValue("Unique");
        FileData[] allrecords = null;
        using (
            SqlConnection conn =
                new SqlConnection(ConfigurationManager.ConnectionStrings["PtcDbModelEntities"].ConnectionString))
        {
            using (
                SqlCommand comm = new SqlCommand("Select Unique1, BinaryData, FileName from PtcDbTracker.dbo.CafFileTable where Unique1=@fileId AND FileName IS NOT NULL", conn))
            {
                comm.Parameters.Add(new SqlParameter("@fileId", fileId));
                conn.Open();
                using (var reader = comm.ExecuteReader())
                {
                    var list = new List<FileData>();
                    while (reader.Read())
                    {
                        list.Add(new FileData { Unique1 = reader.GetInt32(0) });
                        long len = reader.GetBytes(1, 0, null, 0, 0);
                        Byte[] buffer = new byte[len];
                        list.Add(new FileData { BinaryData = (byte)reader.GetBytes(1, 0, buffer, 0, (int)len), FileName = reader.GetString(2) });
                        allrecords = list.ToArray();
                    }
                }
                conn.Close();
            }
        }

        using (var compressedFileStream = new MemoryStream())
        {
            //Create an archive and store the stream in memory.

            using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Update, false))
            {
                if (allrecords != null)
                {
                    foreach (var record in allrecords)
                    {
                        //Create a zip entry for each attachment
                        if (record.FileName != null)
                        {

                            var zipEntry = zipArchive.CreateEntry(record.FileName);

                            //Get the stream of the attachment
                            using (var originalFileStream = new MemoryStream(record.BinaryData))
                            {
                                using (var zipEntryStream = zipEntry.Open())
                                {
                                    //Copy the attachment stream to the zip entry stream
                                    originalFileStream.CopyTo(zipEntryStream);
                                }
                            }
                        }
                    }
                }
                Response.ClearContent();
                Response.ClearHeaders();
                Response.BinaryWrite(compressedFileStream.ToArray());
                Response.AppendHeader("Content-Disposition", "Attachment; filename=result.zip");
                Response.Flush();
                Response.Close();
                zipArchive.Dispose();
                //How Do I Prompt for open or save?
            }
        }

1 Answers1

0

Are you sure the BinaryWrite is getting a valid ByteArray?

In any case here's a tested method to output a file to the Response with the typically needed headers for binary attachments:

        public bool WriteFile(byte[] byteContent, DateTime dtTimeStamp, string urlFilename)
        {
            HttpContext context = HttpContext.Current;
            HttpResponse response = context.Response;
            response.Clear();
            response.ClearHeaders();
            response.ClearContent();
            response.BufferOutput = true;
            response.AppendHeader("Content-Length", byteContent.Length.ToString());
            response.AppendHeader("Content-Type", "application/octet-stream");
            response.AppendHeader("Last-Modified", dtTimeStamp.ToString("R"));//Last-Modified Wed, 28 Aug 2013 10:16:46 GMT 
            response.AppendHeader("Content-Disposition", "inline; filename=\"" + urlFilename + "\"");
            response.BinaryWrite(byteContent);
            response.Flush();
            // Prevents any other content from being sent to the browser
            response.SuppressContent = true;
            context.ApplicationInstance.CompleteRequest();
            return true;
        }
NBO
  • 103
  • 5
  • It appears as though you are correct and there is no data in the array, any idea why this is happening? – Matthew Detweiler May 15 '15 at 18:03
  • the zipArchive has to be disposed, yet leave he stream open see: http://stackoverflow.com/questions/12347775/ziparchive-creates-invalid-zip-file in your case, change the last parameter to the constructor to true: using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Update, true)) and move one curly brace '}' up before the BinaryWrite. – NBO May 16 '15 at 20:45