Have you ever wondered how hard it would be to automatically zip and unzip archives with ASP.NET? It may be easier than you think thanks to the powerful SharpZipLib
open source library. This library provides you with a number of easy to use tools for working with Zip (and GZip, Tar, and BZip2, for that matter) archives in .NET code that make the task of creating and expanding compressed archives relatively easy.
Today we're going to look at how you can use RadUpload and SharpZipLib to upload a Zip archive and then expand it on the server. For our scenario, let's pretend that we want to allow users to upload a zip with photos that we'll then automatically expand into an images directory. In future posts, we'll look at how we can do the inverse, taking files on the server and creating a new zip file that users can download.
Step 1: Setting up RadUpload
RadUpload has come a long way in its short revision history, and it is now very easy to just drop on your page and go. So we'll do just that- drag and drop a RadUpload control onto a page with a RadProgressManager and RadProgressArea that will be used to convey upload progress for larger file uploads. The markup should look something like this:
skinned by the RadUpload stylesheets. (Note: Visual Studio (2008 in this case) doesn't like my values in the ProgressIndicators property. This is a safe warning to ignore- the project will still compile and work correctly.)
When you use the progress tools, you do need to make some modifications to your Web.Config to handle file uploads larger than 4MB. These modifications tell the .NET runtime to allow the long requests necessary for a large file upload and they establish the HttpHandlers/Modules used by RadUpload control for large uploads. Three lines need to be added:
- In the <httpHandlers> section, add:
<add verb="*" path="Telerik.RadUploadProgressHandler.aspx" type="Telerik.WebControls.RadUploadProgressHandler, RadUpload.Net2" />
- In the <httpModules> section, add:
<add name="RadUploadModule" type="Telerik.WebControls.RadUploadHttpModule, RadUpload.Net2" />
- In the <system.web> section, add:
<httpRuntime maxRequestLength="102400" executionTimeout="3600" />
Where maxRequestLength is the total file size allowed and executionTimeout is measured in seconds
Making file input textboxes wider
This will make the invisible file upload controls (that cannot be styled) 54 characters wide. We'll edit the CSS in the skin for our Upload control to make the visible textboxes about 350px wide to match.
Step 2: Working with the uploaded Zip file
Since we're using the RadProgressManager to upload large files, we cannot simply access uploaded files through the RadUpload UploadedFiles collection. Instead, we need to access files via the ProgressManager's RadUploadContext, like this:
When using this approach, RadUpload will not save our files automatically. We need to call the "SaveAs" method for each UploadFile before it is available in the filesytem.
Now the important part: we need to unzip the file.
Unzipping the zip
There are two approaches we can take to unzipping the file when using the SharpZipLib: quick and easy or not as quick with more control. We'll look at both approaches so you can decide which works best for you. Before we do this, though, we need to add a copy of the SharpZipLib assembly to our bin directory (you can download the latest version here).
- Approach 1: Quick and easy
The quick and easy approach utilizes the aptly named FastZip class in the SharpZipLib.Zip namespace. This class enables you to easily zip and unzip entire directories, but it does not easily enable you to evaluate every file before it is zipped or unzipped. So as long we don't mind unzipping everything in our archive, we can write code like this to do the job:
The FastZip.ExtractZip method takes a few arguments:
- Path to the zip file
- Path to unzip the files to
- Overwrite option
- File overwrite delegate (optional)
- RegEx directory filter (optional)
- RegEx file filter (optional)
- Boolean indicating if file time should be restored after unzip
The only thing tricky about these parameters that is not plainly obvious is that the filter properties specify what should be extracted, not what shouldn't. In other words, whatever your filter matches is what will be unzipped- everything else will be ignored.
- Approach 2: Manually expand
If you do not use the FastZip approach, you can gain more control over the unzipping process by using the Zip class directly. This approach takes more code, but it will enable you to have exacting control over the entire unzip process:
You can see the basic process here involves accessing each file in the zip (referred to as "ZipEntry"s) and expanding it into a new file using a FileStream that reads the data out of the ZipEntry. You could inject any code you want in this process to filter unwanted files, change directory structures, or even resize files as they're unzipped.
Clearly, unzipping files with .NET is not that hard. With RadUpload to make the task of uploading large files a snap and SharpZibLib to make unzipping a no brainer, you can easily implement your own upload system that accepts zip files and expands them on the server. In our next installment, we'll look at how you can do the reverse- use SharpZipLib to zip files on the server and make them available for download.
Download sample code used in this article