Create ZipArchive in memory then download to client - c#

I have read several blog posts and questions about this, but I can't get this working. It just downloads a corrupt ZIP archive that is <2KB. I feel like I'm missing something simple with streaming the PDF file to the Zip Archive?
using (var outStream = new MemoryStream())
{
using (ZipArchive archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
{
foreach (string Item in Items)
{
ReportParameter[] prms = new ReportParameter[1];
prms[0] = new ReportParameter("Item", Item, false);
rv.ServerReport.SetParameters(prms);
rv.ShowParameterPrompts = false;
rv.ServerReport.Refresh();
byte[] bytes = rv.ServerReport.Render("PDF", null, out mimeType, out encoding, out extension, out streamids, out warnings);
string fileName = Item + ".pdf";
var fileInArchive = archive.CreateEntry(fileName);
using (var entryStream = fileInArchive.Open())
using (var fileToCompressStream = new MemoryStream(bytes))
{
fileToCompressStream.CopyTo(entryStream);
}
}
}
outStream.Position = 0;
Response.ClearContent();
Response.ClearHeaders();
Response.AppendHeader("content-disposition", "attachment; filename=PDFReports_" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".zip");
Response.Write(outStream);
}

Related

ZipArchive Produces empty ZIP file

I am trying to create a ZipArchive in memory and append several entries with binary data from database. The problem is that after loop, zip sent to client is invalid/empty. Can you please check my code?
using (MemoryStream _memory_stream = new MemoryStream())
{
using (ZipArchive _archive = new ZipArchive(_memory_stream, ZipArchiveMode.Create, true))
{
foreach (byte[] binaryData in this.FileBinaries)
{
ZipArchiveEntry _entry = _archive.CreateEntry(str_filename, CompressionLevel.Optimal);
using (Stream _entryStream = _entry.Open())
{
using (StreamWriter _writer = new StreamWriter(_entryStream))
{
_writer.Write(binaryData);
}
_entryStream.Close();
}
}
}
Response.AppendHeader("content-disposition", "attachment; filename=certificates.zip");
Response.ContentType = "application/zip";
Response.Write(_memory_stream);
}

ZipArchive creates invalid zip file in list from webservices

I have a problem with get files to zip.
The web service is giving me the right files, for example www.XYP.com/GetFile?=1234 , when I open the Url, automaticly downloads the file, but after I zip this document its not correct files, which are destroyes
My code is here:
private void CreatedZipFile(Dictionary<int, string> listChecked)
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (ZipArchive archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
foreach (KeyValuePair<int, string> kvp in listChecked)
{
ZipArchiveEntry demoFile = archive.CreateEntry(kvp.Key.ToString() + kvp.Value.ToString() + ".pdf");
string strDownLoad = System.Configuration.ConfigurationManager.AppSettings["GETFILESERVICES"] + kvp.Key.ToString();
WebService control = new WebService();
var clientnew = new System.Net.WebClient().DownloadData(strDownLoad);
using (var entryStream = demoFile.Open())
{
using (StreamWriter streamWriter = new StreamWriter(entryStream))
{
streamWriter.BaseStream.Write(clientnew, 0, clientnew.Length);
streamWriter.Close();
}
}
}
}
byte[] bytesInStream = memoryStream.ToArray();
Response.ContentType = "application/zip";
Response.AddHeader("content-disposition", "attachment; filename=file.zip");
Response.Buffer = true;
Response.Clear();
Response.BinaryWrite(bytesInStream);
Response.Flush();
//MemoryStream.WriteTo(Response.OutputStream); //works too
Response.End();
}
}
Thanks for help or any advice,

C# ZipArchive: zip file not created

I tried below code to first convert my bytes to compressed bytes and try to create a zip file, but file is not generated. Could someone please suggest!
byte[] result;
var X = 86251;
byte[] compressedBytes;
using (FileStream SourceStream = File.Open(filename, FileMode.Open))
{
SourceStream.Seek(0, SeekOrigin.Begin);
result = new byte[X];
await SourceStream.ReadAsync(result, 0, X);
}
string fileName = "Export_" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".zip";
using (var outStream = new MemoryStream())
{
using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
{
var fileInArchive = archive.CreateEntry(fileName, CompressionLevel.Optimal);
using (var entryStream = fileInArchive.Open())
using (var fileToCompressStream = new MemoryStream(result))
{
fileToCompressStream.CopyTo(entryStream);
}
}
compressedBytes = outStream.ToArray();
}
You're not creating an actual file anywhere. You're just writing to a memory stream. Change it to write to a file.
using (var outStream = new File.Create(fileName))
{
using (var archive = new ZipArchive(outStream, ZipArchiveMode.Create, true))
{
var fileInArchive = archive.CreateEntry(filename, CompressionLevel.Optimal);
using (var entryStream = fileInArchive.Open())
using (var fileToCompressStream = new MemoryStream(result))
{
fileToCompressStream.CopyTo(entryStream);
}
}
}

Zip file shows empty on trying to extract

I am using the following code to download a set of files stored in my database by putting them into a zip file:
SqlDataAdapter adp = new SqlDataAdapter("select FILE_NAME, FILE, content_type from tbl where id = " + "168", Configuration.getSQLConnString("ConnStr"));
DataTable dtFiles = new DataTable();
adp.Fill(dtFiles);
if (dtFiles.Rows.Count > 0)
{
using (var zipStream = new ZipOutputStream(Response.OutputStream))
{
foreach (DataRow dr in dtFiles.Rows)
{
byte[] bytes;
string fileName, contentType;
fileName = dr["File_Name"].ToString();
bytes = (byte[])dr["File"];
contentType = dr["Content_Type"].ToString();
Response.Clear();
Response.Buffer = true;
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.AddHeader("Content-Disposition", "attachment; filename=Files.zip");
Response.ContentType = "application/zip";
byte[] fileBytes = bytes;
ZipEntry fileEntry = new ZipEntry(ZipEntry.CleanName(fileName));
fileEntry.Size = fileBytes.Length;
zipStream.SetLevel(3);
zipStream.PutNextEntry(fileEntry);
zipStream.Write(fileBytes, 0, fileBytes.Length);
zipStream.CloseEntry();
}
zipStream.Flush();
zipStream.Close();
}
}
The zip file gets generated and is downloaded and it also shows me a size of about 2Mb but then when I extract the zip file it shows me the following error:
Can someone please point out what is that I am doing wrong?
ZipOutputStream did not help me at all; tried breaking my head over it but nothing helped. Then I came across this library called DotNetZip and here's the code to download files stored in the database into a zip file:
using (ZipFile zip = new ZipFile())
{
foreach (DataRow dr in dtResumes.Rows)
{
zip.AddEntry(dr["File_Name"].ToString(), (byte[])dr["Resume"]);
}
zip.Save("C:\\Test\\MyZipFile.zip");
}

C# No Data in Folder after Downloading ASP

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?
}
}
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;
}

Categories

Resources