Yes, DotNetZip works in a webservice. The way you're trying to do it is not right.
The HttpContext is something that is present in a web page. In the original .NET Web services runtime, aka ASMX, HttpContext was present and available inside the code for the webservice. But, using HttpContext is a pretty sketchy thing to do, especially
now that WCF is the preferred web services (and communications) runtime for .NET these days. Within WCF, there is no HttpContext, because WCF is not tightly bound to http.
If you're using WCF, then you're going to want to stream the zip content out. Check this page for some background on how to do that: http://msdn.microsoft.com/en-us/library/ms731913.aspx
But... you're in luck! Your question has been asked before, and I put some effort into working out an efficient solution with the previous person. We had a back-and-forth, that you can read
here. The solution involves the use of the ZipOutputStream from DotNetZip, and anonymous pipes, via the
AnonymousPipeServerStream classes that were added to .NET in v3.5.
To sum it up, you can define a WCF interface like this:
public interface IImageService
public Stream GetFileZip(string filenames);
(for more on defining interfaces in WCF, see
this page on msdn)
The code implementing the interface is then, like this:
public Stream GetFileZip(string filenames)
return GetPipedStream(s =>
byte bytes = new byte; // any size will do
using (ZipOutputStream zos = new ZipOutputStream(s, true))
for (int i = 0; i < filenames.Length; i++)
zos.PutNextEntry(filenames[i]); // the i'th filename
using (FileStream fs = File.OpenRead(filename[i]))
while((n = fs.Read(bytes,0,bytes.Length))>0)
zos.Write(bytes, 0, n);
Obviously you'd need to put logic in there to detect and handle error conditions - such as when the specified filename does not exist. I left that stuff out for clarity.
The GetPipedStream is a utility method defined this way:
static Stream GetPipedStream(Action<Stream> writeAction)
AnonymousPipeServerStream pipeServer = new AnonymousPipeServerStream();
return new AnonymousPipeClientStream(pipeServer.GetClientHandleAsString());
Don't worry about the code for GetPipedStream - it's boilerplate and you don't need to understand it too much, in order to use it.
What you get with this is a WCF service that zips up the files on a given list, and streams the resulting zipfile back to the requester. It does not create a temporary zip file in the server filesystem, instead it just streams out the zip to the requester.
It should be very memory efficient and very fast. You can use it over any WCF transport channel that supports streams - http, tcp, or other. Because of the use of anonymous pipes it works only with .NET 3.5 and later.