views:

147

answers:

1

Let's say that I have a website where I'd like users to be able to download a certain group of files. There will be checkboxes and listboxes of options for users to choose from, so that they can select what parts they want to include and what they don't want to download. Then, they click the Download button and their browser downloads a zip file containing only the things they selected.

I want to accomplish such a hypothetical situation with ASP.NET and C#. Of course, I could make zip files of all the permutations, but that would take a LOT of time. Is it somehow possible, if I have the file paths of files stored on my server, to take some of those files, zip them up (in memory or on disk and then delete it), and send the zip file to the client thru the Response?

UPDATE: I just found the following question and code sample thru the Related box:

private void sendToClient(Dictionary<string, string> reportDic)
{
    Response.Clear();
    Response.BufferOutput = false;
    String ReadmeText = "some text";
    Response.ContentType = "application/zip";
    Response.AddHeader("content-disposition", "filename=" + "filename.zip");
    using (ZipFile zip = new ZipFile())
    {
        zip.AddEntry("Readme.txt", ReadmeText);
        zip.Save(Response.OutputStream);
    }
    Response.Close();
}

It uses DotNetZip to zip up the file.

Do you think this is what I'm looking for? I'm going to go read the docs of DotNetZip.

+1  A: 

Yes it is possible to build write a GZip stream to the response in memory like a normal stream. example at:

http://www.vwd-cms.com/forum/forums.aspx?topic=18

Although I don't know why you would to delete it after? Zipping and IO access takes resources, a good way to save it is to cache it. I personally would use Enum flags and bit arithmetic to capture all the user options into a single integer and append it to the filename so you can return it again if someone asks for exactly the same configuration.

Edit: added example

[Flags] //doesn't mean anything just declarative
public enum UserOptions
{
    None = 0,
    Option1 = 1 << 0,  //1  or  0001
    Option2 = 1 << 1,  //2  or  0010
    Option3 = 1 << 2,  //4  or  0100
    Option4 = 1 << 3,  //8  or  1000
}

var userOptions = UserOptions.None;

if (Request["UserWantsOption2"])
{
  userOptions |= UserOptions.Option2;  //userOptions = 2
}
if (Request["UserWantsOption4"])
{
  userOptions |= UserOptions.Option4;  //userOptions = 10 (2 + 8)
}

So as we're just using bit flags together if you end up with a value of '10' then it means that the user has selected options 2 and 4 as there is no other combinations possible to add up to that value.

mythz
That's a great caching idea! Could you give me a little sample code for the Enum flags and bit arithmetic into a single integer thing you mentioned? Thanks!
Maxim Zaslavsky
"doesn't mean anything just declarative" is wrong. An enumeration is treated differently by the compiler and the runtime if it has the FlagsAttribute: http://msdn.microsoft.com/en-us/library/system.flagsattribute.aspx
bzlm
The example will work with or without the [Flags] attribute. I couldn't see anywhere in that link where it says it would be treated differently by the compiler or runtime. Can you be more specific?
mythz