Uploader for Silverlight
Compressing and Uploading Files

You may want to compress files before uploading them to the server. To do so, you can use the C1Zip class included with Silverlight Edition along with the C1Uploader class. In this topic we create an application to zip and upload files.

Complete the following steps to create the UI:

  1. In Visual Studio 2008, select File | New | Project.
  2. In the New Project dialog box, select a language in the left pane, and in the templates list, select Silverlight Application. Enter a Name for your project and click OK. The New Silverlight Application dialog box appears.
  3. Click OK to accept default settings, close the New Silverlight Application dialog box, and create your project. The MainPage.xaml file opens.
  4. In the Solution Explorer window, right-click the project and select Add Reference.
  5. In the Add Reference dialog box, locate and select the C1.Silverlight.Zip.dll and C1.Silverlight.Uploader.dll assemblies and click OK to add references to your project.
  6. Place the cursor in the XAML window of the project, and delete the <Grid> and </Grid> tags. We replace these tags in the next step.
  7. In the MainPage.xaml file, between the <UserControl> and </UserControl> tags, add the following XAML markup:
    XAML
    Copy Code
    <StackPanel Orientation="Horizontal" x:Name="LayoutRoot" Background="White" HorizontalAlignment="Center" VerticalAlignment="Center"
    MinHeight="400">
        <Border Padding="5" BorderBrush="Black" BorderThickness="1" Margin="2" MinWidth="200">
            <StackPanel>
                <Button Content="Open files" Click="OpenFiles" />
                <TextBlock Text="Opened files:" FontWeight="Bold" Margin="10"/>
                <ItemsControl Name="files"/>
            </StackPanel>
        </Border>
        <Button Content="Zip and upload files >" Grid.Column="1" VerticalAlignment="Center" Margin="10" Click="ZipAndUpload"
    Name="zipAndUploladButton"/>
        <Border Padding="5" BorderBrush="Black" BorderThickness="1" Margin="2" Grid.Column="2">
            <StackPanel>
                <TextBlock Text="Zipped files on the server:" FontWeight="Bold" Margin="10"/>
                <ItemsControl Name="zips" Background="White"/>
            </StackPanel>
        </Border>
    </StackPanel>
    
    This markup creates panels and a button that users click to zip and upload files to the server.

Complete the following steps to add event handling to your project:

  1. In the Solution Explorer, right-click the MyProjectWeb application where "MyProject" is the name of your project application. Select New Folder and name the folder "Zips." This folder contains the compressed files.
  2. In the Solution Explorer, right-click MainPage.xaml file and select View Code to switch to Code view.
  3. In Code view, add the following import statements to the top of the page if they are not included:
    Visual Basic
    Copy Code
    Imports System.IO
    Imports C1.C1Zip
    Imports C1.Silverlight.Uploader
    

     

    C#
    Copy Code
    using System.IO;
    using C1.C1Zip;
    using C1.Silverlight.Uploader;
    
  4. Define the following variables just inside the MainPage class:
    Visual Basic
    Copy Code
    Dim fileInfos As IEnumerable(Of FileInfo)
    Dim zipCount As Integer = 0
    

     

    C#
    Copy Code
    IEnumerable<FileInfo> fileInfos;
    int zipCount = 0;
    
  5. Below all the other methods in the MainPage class, add the following event handler to the MainPage.xaml.cs file:
    Visual Basic
    Copy Code
    Private Sub OpenFiles(ByVal sender As Object, ByVal e As RoutedEventArgs)
        Dim dialog = New OpenFileDialog()
        dialog.ShowDialog()
        If dialog.Files Is Nothing Then
            Exit Sub
        End If
        fileInfos = dialog.Files
        files.ItemsSource = fileInfos.[Select](Function(fi) fi.Name)
        zipAndUploladButton.IsEnabled = fileInfos.Any()
    End Sub
    

     

    C#
    Copy Code
    private void OpenFiles(object sender, RoutedEventArgs e)
    {
        var dialog = new OpenFileDialog { Multiselect = true };
        dialog.ShowDialog();
        if (dialog.Files == null)
        {
            return;
        }
        fileInfos = dialog.Files;
        files.ItemsSource = fileInfos.Select(fi => fi.Name);
        zipAndUploladButton.IsEnabled = fileInfos.Any();
    }
    
    This event handler initially displays an OpenFileDialog for the user to select files to upload.
  6. Add the following event handler to your project to zip and upload files:
    Visual Basic
    Copy Code
    Private Sub ZipAndUpload(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' create memory stream and zip file
        Dim stream = New MemoryStream()
        ' set MemoryThreshold to prevent C1ZipFile from trying to use a temporary file
        Dim zip = New C1ZipFile(stream, True)
    
        ' add files to zip
        For Each fileInfo In fileInfos
            Dim fileStream = fileInfo.OpenRead()
            zip.Entries.Add(fileStream, fileInfo.Name)
            fileStream.Close()
        Next
    
        ' create uploader
        Dim uploader As C1Uploader = New C1UploaderPost(BuildAbsoluteUri("Upload.ashx"))
    
        ' set the stream at the beginning and add it to the uploader
        stream.Seek(0, SeekOrigin.Begin)
        Dim zipName = System.Threading.Interlocked.Increment(zipCount) & ".zip"
        uploader.AddFile(zipName, stream)
    
        ' when the upload is complete show it on the zips list
            Dim hb As New HyperlinkButton
            hb.Content = zipName
            hb.NavigateUri = BuildAbsoluteUri("Zips/" + zipName)
            If uploader.IsBusy = False Then
                Me.zips.Items.Add(hb)
            End If 
        ' upload zip file!
        uploader.BeginUploadFiles()
    End Sub
    

     

    C#
    Copy Code
    private void ZipAndUpload(object sender, RoutedEventArgs e)
    {
        // create memory stream and zip file
        var stream = new MemoryStream();
        var zip = new C1ZipFile(stream, true)
        {
            // set MemoryThreshold to prevent C1ZipFile from trying to use a temporary file
            MemoryThreshold = int.MaxValue,
            CompressionLevel = CompressionLevelEnum.BestCompression
        };
    
        // add files to zip
        foreach (var fileInfo in fileInfos)
        {
            var fileStream = fileInfo.OpenRead();
            zip.Entries.Add(fileStream, fileInfo.Name);
            fileStream.Close();
        }
    
        // create uploader
        C1Uploader uploader = new C1UploaderPost(BuildAbsoluteUri("Upload.ashx"));
    
        // set the stream at the beginning and add it to the uploader
        stream.Seek(0, SeekOrigin.Begin);
        var zipName = ++zipCount + ".zip";
        uploader.AddFile(zipName, stream);
    
        // when the upload is complete show it on the zips list
        uploader.UploadCompleted += (s, e2) =>
        {
            zips.Items.Add(new HyperlinkButton
            {
                Content = zipName,
                NavigateUri = BuildAbsoluteUri("Zips/" + zipName)
            });
        };
    
        // upload zip file!
        uploader.BeginUploadFiles();
    }
    
  7. Add the following event handler to your project:
    Visual Basic
    Copy Code
    Public Shared Function BuildAbsoluteUri(ByVal relativeUri As String) As Uri
        ' Get current absolute Uri; this depends on where the app is deployed
        Dim uri As Uri = System.Windows.Browser.HtmlPage.Document.DocumentUri
        Dim uriString As String = uri.AbsoluteUri
    
        ' Replace page name with relative service Uri
        Dim ls As Integer = uriString.LastIndexOf("/"c)
        uriString = uriString.Substring(0, ls + 1) + relativeUri
    
        ' Return new Uri
        Return New Uri(uriString, UriKind.Absolute)
    End Function
    

     

    C#
    Copy Code
    public static Uri BuildAbsoluteUri(string relativeUri)
    {
        // Get current absolute Uri; this depends on where the app is deployed
        Uri uri = System.Windows.Browser.HtmlPage.Document.DocumentUri;
        string uriString = uri.AbsoluteUri;
    
        // Replace page name with relative service Uri
        int ls = uriString.LastIndexOf('/');
        uriString = uriString.Substring(0, ls + 1) + relativeUri;
    
        // Return new Uri
        return new Uri(uriString, UriKind.Absolute);
    }
    

Complete the following steps to add a method to clean up and add files to the zip file:

  1. In the Visual Studio Solution Explorer, right-click the MyProjectWeb solution where "MyProject" is the name of your project. Select the Add | New Item option.
  2. In the Add New Item dialog box, select the Generic Handler template and name the new class "Upload.ashx" (this is the Uri from the C1Uploader object).
  3. Click Add to add the file to your project and close the Add New Item dialog box.
  4. Open the Upload.ashx code file and add the following import statement to the top of the page if it is not included:
    Visual Basic
    Copy Code
    Imports System.Web.Services
    

     

    C#
    Copy Code
    using System.Web.Services;
    
  5. Replace the default implementation of the ProcessRequest method with the following code:
    Visual Basic
    Copy Code
    Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
        Const MAXFILES As Integer = 30
    
        ' Clean up
        Dim path As String = context.Request.MapPath("Zips")
        Dim files As String() = System.IO.Directory.GetFiles(path)
        If files.Length >= MAXFILES Then
            For Each fileName As String In files
            System.IO.File.Delete(fileName)
            Next
        End If
    
        ' Get files being uploaded
        Dim i As Integer = 0
        While i < context.Request.Files.Count AndAlso i < MAXFILES
            Dim file As HttpPostedFile = context.Request.Files(i)
    
            ' Save file to the Zips folder
            Dim fileName As String = context.Request.MapPath("Zips/" & file.FileName)
            file.SaveAs(fileName)       
            i += 1
        End While
    End Sub
    

     

    C#
    Copy Code
    public void ProcessRequest(HttpContext context)
    {
        const int MAXFILES = 30;
        // Clean up
        string path = context.Request.MapPath("Zips");
        string[] files = System.IO.Directory.GetFiles(path);
        if (files.Length >= MAXFILES)
        {
            foreach (string fileName in files)
                System.IO.File.Delete(fileName);
        }
    
        // Get files being uploaded
        for (int i = 0; i < context.Request.Files.Count && i < MAXFILES; i++)
        {
            HttpPostedFile file = context.Request.Files[i];
            // Save file to the Zips folder
            string fileName = context.Request.MapPath("Zips/" + file.FileName);
                file.SaveAs(fileName);
            }
        }
    }
    
    This code starts by cleaning up the zips folder in case there are more than 30 files in it. After the clean-up, the code loops through the files in the context.Request.Files collection and saves each file into the Zips folder.    

What You've Accomplished

You've successfully created a Silverlight application that uploads zipped files. To observe how the application works, complete the following steps:

  1. To run the application, select Debug | Start Debugging.
  2. Click the Open files button to choose files to upload.
  3. In the Open dialog box, select a file or multiple files to upload, and click the Open button. The dialog box closes.
  4. Click the Zip and upload files button to upload the selected files.
  5. A link to the zipped file appears. (The name is "1.zip" if it is the first file uploaded.)
  6. Click on the link to the zip file and save it to your computer.
  7. Extract the zip file and observe that the items you uploaded exist in the file.

 

See Also

 

 


Copyright (c) GrapeCity, inc. All rights reserved.

Product Support Forum  |  Documentation Feedback