I am trying to create zip file dynamically on the server that includes photos from online services. But when I try to open the file, WinRar sais the the file is unknown format or damaged.
this is the code:
MemoryStream stream = new MemoryStream();
Package package = ZipPackage.Open(stream, FileMode.Create, FileAccess.ReadWrite);
foreach (Order o in orders)
{
o.GetImages();
Parallel.ForEach(o.Images, (Dictionary<string, object> image) =>
{
string imageId = (string)image["ID"];
int orderId = (int)image["OrderId"];
string fileName = (string)image["FileName"];
string url = (string)image["URL"];
if (string.IsNullOrEmpty(fileName))
{
System.Net.WebClient wc = new System.Net.WebClient();
byte[] data = wc.DownloadData(url);
MemoryStream ms = new MemoryStream(data);
ms.Write(data, 0, data.Length);
string ext;
switch(wc.ResponseHeaders["Content-Type"])
{
case "image/jpeg":
case "image/jpg":
ext = "jpg";
break;
case "image/png":
ext = "png";
break;
case "image/gif":
ext = "gif";
break;
default :
ext = "un";
break;
}
Uri uri = new Uri("/" + orderId.ToString() + "/" + imageId + "." + ext, UriKind.Relative);
var part = package.CreatePart(uri, wc.ResponseHeaders["Content-Type"], CompressionOption.NotCompressed);
var pstream = part.GetStream(FileMode.Open, FileAccess.ReadWrite);
pstream.Write(data, 0, data.Length);
var rel = package.CreateRelationship(part.Uri, TargetMode.Internal, "http://example.com/AlbumImage");
}
});
}
package.Flush();
byte[] fileBytes = new byte[stream.Length];
stream.Read(fileBytes, 0, Convert.ToInt32(stream.Length));
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=Orders.zip");
Response.AddHeader("Content-Length", stream.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.BinaryWrite(fileBytes);
Response.End();
It's all about Pack Uris. We also have been beaten by them. Here is working sample for storing two files in zip. Code just copied from our project with removing some private data.
var dataFilePath = Path.GetFileName(dataFileName);
var dataFileUri = PackUriHelper.CreatePartUri(new Uri(dataFilePath, UriKind.Relative));
// Create the Package
using (var package = Package.Open(filePath, FileMode.Create))
{
// Add the diagram view part to the Package
var pkgPart = package.CreatePart(dataFileUri, MediaTypeNames.Application.Octet);
var pkgStream = pkgPart.GetStream();
// Copy the data to the model view part
// diagramFileName Encoding.Default.GetBytes(text)
using (var modelStream = new FileStream(dataFileName, FileMode.Open, FileAccess.Read))
{
const int bufSize = 0x1000;
var buf = new byte[bufSize];
int bytesRead;
while ((bytesRead = modelStream.Read(buf, 0, bufSize)) > 0)
{
pkgStream.Write(buf, 0, bytesRead);
}
}
// Add a context Part to the Package
var pkgPartContext = package.CreatePart(ctxUri, MediaTypeNames.Application.Octet);
var ctxPkgStream = pkgPartContext.GetStream();
// Copy the data to the context part
using (var ctxStream = new FileStream(ctxFileName, FileMode.Open, FileAccess.Read))
{
const int bufSize = 0x1000;
var buf = new byte[bufSize];
int bytesRead;
while ((bytesRead = ctxStream.Read(buf, 0, bufSize)) > 0)
{
ctxPkgStream.Write(buf, 0, bytesRead);
}
}
}
// remove tmp files
File.Delete(ctxFileName);
File.Delete(dataFileName);