Using a WebClient to download and access a ZIP package

The OpenReadAsysc() function of the WebClient class is similar to the DownloadStringAsync() function, except it opens a Uri object as a stream. The OpenReadAsysc() accepts a Uri object as an argument and retrieves the contents of the path specified by the Uri as a stream. For example:

client.OpenReadAsync(new Uri("image.jpg", UriKind.Relative));

To access the result of the OpenReadAsysc() function, you need to attach an OpenReadCompleted event handler function to the WebClient object. For example, the following line of code attaches an OpenReadCompleted event handler function doDownload CompletedO to a WebClient object named client.

client.DownloadStringCompleted +=

new DownloadStringCompletedEventHandler(doDownloadCompleted);

The OpenReadCompleted event handler function must accept an object, the sender, as the first argument and an OpenReadCompletedEventArgs as the second argument.

Inside the OpenReadCompleted event handler function the downloaded file stream can be accessed using the result property of the OpenReadCompletedEventArgs argument. The result property is of Stream type and can be used to access the contents of the downloaded file.

For example, the following OpenReadCompleted event handler function uses the result property to access the file stream of an image file and uses it to set the Source property of an Image control named img:

void doDownloadCompleted(object sender, OpenReadCompletedEventArgs e)

StreamResourcelnfo imageStream =

new StreamResourceInfo(e.Result as Stream, null); Bitmaplmage imgsrc = new BitmapImage(); imgsrc.SetSource(imagelnfo.Stream); img.Source = imgsrc;

Listings 14.5 and 14.6 show an example of using a WebClient object to download a ZIP file from the server. The code then uses the contents of the ZIP file to set various controls in a Silverlight application.

The code in Listing 14.5 defines a simple interface with a Button control, downloadBtn, to initiate a file download, a TextBlock control, titleText , and a Grid control, imageGrid.

LISTING 14.5

Page.xaml File That Defines a Button Control to Initiate a File Download and a TextBlock Control and Grid Control Used to Display the Results

<UserControl x:Class="DownloaderApp.Page"

xmlns="http://schemas.microsoft.com/client/2 0 07" xmlns:x="http://schemas.microsoft.com/winfx/2 00 6/xaml" Width=M400M Height=M4 00M>

<Grid x:Name="LayoutRoot" Background=MBlackM> <TextBlock x:Name=MtitleTextM

FontSize=M50M Foreground="White" HorizontalAlignment=MCenterM/> <Grid x:Name=MimageGridM

HorizontalAlignment=MCenterM VerticalAlignment="Center" Height=M240M Width=M300M /> <Button x:Name="downloadBtn" Content=MDownload Content" Height="3 0" Width="150" VerticalAlignment="Bottom" Margin="10" />

The code in Listing 14.6 first implements the System.Net library for the WebClient class, the System.IO library for the StreamReader and Stream classes, the System.Windows. Resources library for the StreamResourceInfo class and the System.Windows.Media. Imaging library for the BitmapImage class.

Inside the Page() constructor, the code attaches a Click event handler, doDownload() , to the downloadBtn control defined in Listing 14.5. Inside the doDownload () event handler, the WebClient object, client, is created.

An OpenAsyncCompleted event handler, DownloadZipCompleted() , is attached to the client object. Then the following line of code is used to create a Uri object for the content.zip file, shown in Figure 14.2, and initiates the file download:

client.OpenReadAsync(new Uri(filename, UriKind.Relative));

LISTING 14.6

Page.xaml.cs File That Creates a WebClient and Uses It to Download the Contents of a File Named readme.txt using System;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Media;

using System.Net; using System.IO; using System.Windows.Resources; using System.Windows.Media.Imaging;

namespace DownloaderApp {

public partial class Page : UserControl {

InitializeComponent();

downloadBtn.Click += new RoutedEventHandler(doDownload);

void doDownload(object sender, RoutedEventArgs e) {

string filename ="content.zip";

WebClient client = new WebClient(); client.OpenReadCompleted +=

new OpenReadCompletedEventHandler(DownloadZipCompleted); client.OpenReadAsync(new Uri(filename, UriKind.Relative));

void DownloadZipCompleted(object sender,

OpenReadCompletedEventArgs e)

StreamResourceInfo zipInfo =

new StreamResourceInfo(e.Result, null);

//Get Image from ZIP

StreamResourceInfo imagelnfo = Application.GetResourceStream(

zipInfo, new Uri("image.jpgM, UriKind.Relative)); Image img = new Image(); img.Height = 24 0;

BitmapImage imgsrc = new BitmapImage(); imgsrc.SetSource(imageInfo.Stream); img.Source = imgsrc; imageGrid.Children.Clear(); imageGrid.Children.Add(img);

//Get Audio from ZIP

StreamResourceInfo audioInfo = Application.GetResourceStream(

zipInfo, new Uri("music.mp3", UriKind.Relative)); MediaElement music = new MediaElement(); music.SetSource(audioInfo.Stream); LayoutRoot.Children.Add(music); music.Play();

//Get Font from ZIP

StreamResourceInfo fontInfo = Application.GetResourceStream(

zipInfo, new Uri("font.ttf", UriKind.Relative)); FontSource newFont = new FontSource(fontInfo.Stream); titleText.FontSource = newFont;

StreamResourceInfo fontName = Application.GetResourceStream( zipInfo, new Uri("fontinfo.txt", UriKind.Relative)); StreamReader reader = new StreamReader(fontName.Stream); titleText.FontFamily = new FontFamily(reader.ReadLine());

//Get Text from ZIP

StreamResourceInfo dataInfo = Application.GetResourceStream(

zipInfo, new Uri("data.txt", UriKind.Relative)); StreamReader dataReader = new StreamReader(dataInfo.Stream); titleText.Text = dataReader.ReadToEnd();

Inside the handler DownloadZipCompleted () function, the following line of code uses the result property of the DownloadStringCompletedEventArgs argument to create a StreamResourceInfo object that can access the downloaded ZIP file stream:

StreamResourcelnfo zipInfo = new StreamResourceInfo(e.Result, null);

Using the zipInfo SreamResourcelnfo object, the code is then able to access the individual components of the ZIP file. For example, the following line of code is used to access an MP3 file stored in the ZIP file:

StreamResourcelnfo audiolnfo = Application.GetResourceStream( zipInfo, new Uri("music.mp3", UriKind.Relative));

The code in the DownloadZipCompleted () function of Listing 14.6 uses this same technique to access each of the different files in the content.zip file shown in Figure 14.2. The image.jpg file is read and used to create a new Image object that is added as a child to the imageGrid control.

The music.mp3 file is read and used to create a new MediaElement control that is added to the LayoutRoot control. The Play() function of the MediaElement control is used to start playback of the music file.

The font.ttf file is used to set the FontSource property of the titleText control. To set the FontFamily property, the typeface name is read from the fontinfo.txt file.

The data.txt file is read using a StreamReader, and the contents are applied as the Text property of the titleText control.

FIGURE 14.2

Contents of the content.zip file used in Listing 14.6

FIGURE 14.2

Contents of the content.zip file used in Listing 14.6

The results of the application defined by Listings 14.5 and 14.6 are shown in Figure 14.3. When the user clicks Download Content, the contents of the content.zip file are downloaded and the contents are used to add an image and music, and set the typeface and text of the Silverlight application dynamically.

FIGURE 14.3

Silverlight application that dynamically downloads a ZIP file and uses the contents to dynamically change several controls

FIGURE 14.3

0 0

Post a comment

  • Receive news updates via email from this site