By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,694 Members | 2,121 Online
Bytes IT Community
Submit an Article
Got Smarts?
Share your bits of IT knowledge by writing an article on Bytes.

Building A Silverlight (2.0) Multi-File Uploader

Curtis Rutland
Expert 2.5K+
P: 3,256
Building A Silverlight (2.0) Multi-File Uploader
All source code is C#. VB.NET source is coming soon.

Note: This project requires Visual Studio 2008 SP1 or Visual Web Developer 2008 SP1 and Silverlight 2.0. To get these tools please visit this page
Get Started : The Official Microsoft Silverlight Site
and follow Step 1.


Occasionally you find the need to have users upload multiple files at once. You could use multiple FileUpload controls, or you could dynamically create them, but if you want a rich client experience, a good way do to this is with Silverlight. This article assumes very little pre-existing Silverlight knowledge.

One important thing to know about Silverlight: it is executed on the client, not the server. This is exactly the opposite of ASP.NET, where all code is executed on the server. So Silverlight can easily get the files, but it can’t save them directly to the webserver. So we need something to bridge the gap.

What we will do is create an ASP.NET Web Service. This web service will expose a method that will allow a client to upload a file with a name. Presumably any client can consume this service, not just your Silverlight application, unless you implement some sort of SOAP Header authentication, but that’s beyond the scope of this article.

So the plan is to use Silverlight as our rich front end, which will connect to our ASP.NET web service backend. In this example, we will be creating a new project. If you have an existing Web Site or Web Application project, the procedures will be slightly different. I’ll explain the differences as we go along.

Let’s create the new project:


Make sure that the dropdown in the top right corner is set to .NET Framework 3.5, otherwise the list of project types will be empty for Silverlight.

Another dialog will pop up asking you if you want to create a new Web Application Project to link this Silverlight project to. Click OK.



If you are creating this Silverlight app for an existing project, you should right-click on the solution file for your project in Visual Studio and select Add New Project.


And add a Silverlight Project. The dialog will now ask if you want to link to the existing project.


Click OK.

Now that we have a Silverlight project and a linked Web Site/Web Application set up, it’s time to create the web service.

Writing the Uploader Service
Begin by adding a web service to our project. Right-Click on the Web Application Project, and Select Add New Item:


Select Web, and Find the Web Service Icon. Name the new file FileUploadService.asmx.


Now the web service has been created. Here's a few setup steps we need to take:
  • Delete the Hello World method that has been automatically created. Remember to delete the [WebMethod] decoration as well.
  • Add this using statement to the top with the rest of the statements:
    Expand|Select|Wrap|Line Numbers
    1. using System.IO;
  • You can leave the namespace definition the same, or you can change it to your own URL. It isn't very important.
  • Lastly, add a folder to your Web Application called upload.


Now that we've set up our web service, let’s examine the logic we will use. All web service calls in Silverlight are asynchronous. Explanation: Instead of calling a method, and having the program wait for it to complete before finishing, you create an event handler to be fired when the method is complete. Then you start the method, and your program continues without it. The processing of that method is done on another thread. When it is finished, the Completed event is fired, and the handler you defined is triggered.

What this means for us is that we can invoke several requests at once…we don’t have to upload a list or array of files, we can make multiple requests to upload single files and they will be processed simultaneously. Knowing this will help us define our service.

We are going to expose just one web method. We’ll call it UploadFile. This method will take two parameters: a byte[], and a string. Here’s the code:


Remember the [WebMethod] decoration. It specifies that this method will be exposed for clients to invoke.

Basically, what this method does is accept an array of bytes and a filename. Then it grabs the server’s path to the upload directory and writes the file to disk. If the method fails, it returns false, otherwise, it returns true. Currently this method will overwrite any file with the same name. Later, you can implement some renaming logic to prevent this.

That’s it! That’s all there is to the web service. Make sure your solution will build and proceeded to creating the Silverlight app.

Creating the Silverlight Frontend
Open the Page.xaml file in your Silverlight project. Silverlight uses a markup language called XAML for layout and content. This is a special variation on XML, so most of the rules of XML apply, such as closing all tags. The root tag is a UserControl tag. This will define your Silverlight control.

The first thing we want to do is redefine the size of our control. For the purposes of this demonstration, we'll use 300 x 150 pixels. So in the root tag, change the Width and Height attributes to match. By default they are the last attributes.

Here's what you should have so far:


The grid will be our layout root. There are other layout containers including StackPanels and Canvases, but for this instance, a Grid will work well.

Let's define our presentation logic. We want to allow users to add several files to a queue, and then upload them all when they have a good list. We should allow them to remove files that they didn't mean to add. So, we will need a ListBox and two Buttons. Let's arrange them on two rows, with the top row holding the ListBox.

So to configure our grid to have two rows, we need to add some RowDefinitions. RowDefinitions can be either absolute or relative. We'll make these relative. Add this code:


Note that the rows will be distributed across the entire size of the grid, with the first being five times larger than the second.

Now that we have defined our grid, let's add some of our controls.


Let's discuss some common attributes for a moment. x:Name is the name that we will refer to our items with in our codebehind file. This is the equivalent of the ID tag in ASP.NET. Also, many controls have Events. For example, the ListBox we just added has several. When you add an event, IntelliSense will prompt you to automatically add the event handler name and definition.


Just press Tab or Return and this will be filled in for you.

So, we've added a ListBox with a KeyDown event. Next we've added a new Grid. You can stack these elements inside each other. Inside the new grid, we've defined two columns and added two Buttons, each with their own Click Event handlers. Just do these like you did for the ListBox, and the handlers will automatically be created on the back end.

Now we need to add some code to the ListBox. A Silverlight DataList has an Item array of objects. The properties of these objects can be bound to Silverlight controls in a ListBox's DataTemplate. In this case, we are going to be using FileInfo objects. So we can use the Name property of the FileInfo to bind to a TextBlock to make up an ItemTemplate. We could make this more intricate, with file sizes or other properties bound to other controls, but we'll keep it simple for now. Here's the code:



We're almost ready to start the real coding. We just need some way to disable the controls and communicate with the users that we are uploading their files. Add this code underneath the Grid holding the Buttons:


Note that we've added a StackPanel on the same row as the ListBox, but we've set its RowSpan attribute to 2. This will effectively make it cover the whole control. We've set the background color to a sort of Gray, and the Opacity to .85 (out of a possible 1).

A StackPanel does exactly what it says...it stacks items inside a panel, either Horizontally or Vertically. By default, it stacks vertically. You could change this by setting the Orientation property.

Notice that we've placed a TextBox and a Button in the StackPanel. Make sure you follow the procedure described earlier on how to add events, as the Button we've added has a Click event.

Also, notice that we've set the Visibility of the StackPanel to "Collapsed." This way, it will be invisible. If you want to see how it will look when we make it visible, change it to "Visible." When this panel is visible, it is in front of the other controls, so you can't click them.

Now we're ready to start with the codebehind. First, make sure you save the current page. You have to save before the codebehind will recognize the x:Name attributes. Then you can right-click anywhere on the Page.xaml page (editor or preview) and select "View Code."

This will open Page.xaml.cs. Here's what it should have to start with:


The methods you have may not be in this exact order. A few setup items:
  • Add this code to the using statements at the top:
    Expand|Select|Wrap|Line Numbers
    1. using System.IO;
  • Add this code directly above the constructor (the public Page method)
    Expand|Select|Wrap|Line Numbers
    1. private int counter = 0;
And we're ready to start coding.

Let's fill in the code for the event handlers. First, the one called bOpenFileDialog_Click.


This code will open a FileDialog and let the user pick a file. If the user does not select a file or picks cancel, nothing happens. If they do, a FileInfo object is added to our ListBox's Items array. The ?? operator is the null-coalescing operator. What it does is evaluates the left. If it isn't null, it returns the left value. If it is, it returns the right value.

Now for the lbFileList_KeyDown handler:


This will let us delete an item in the list.

Now, the bClear_Click handler:


This will clear the textbox, array, and hide the Uploading screen.

Adding the Service Reference
Now comes the tricky part. You must add a service reference for this next part, but what's the address to your web service? Well, let's find out. Hit F5 to run your app, and navigate to FileUploadService.asmx . Your URL will have a port number on it. Here's an example:


That's the address of your service. This will only work while the development server is running (when Visual Studio is running and you have debugged your project)! So when you shut down Visual Studio, that address is no longer valid, and may not be when you start it up again. So make sure to check that every time you reload this project. Once you publish this project to a web server, you can change that address to point to the permanent address on the web.

Now to add the service reference. Right-Click on the References folder in your Silverlight project, and click "Add Service Reference."


Paste the address in and click Discover. When it finds the service, change the Namespace to FileUploadService, and click OK.



Now we have a reference to our service, let's create a client. Add this code:


in the bSubmit_Click method. The comments explain what is happening. The last line is important: as you type it you will see this:

Hit Tab twice to generate the handler for the FileUploadComplete event automatically. This will add another method to the page.

Let's finish out the bSubmit_Click method while we are here. Add this code in below what we just added:


Again, the comments explain what is happening. We increment the counter to note that we've added another async call to our web method.

Now, let's fill in service_UploadFileCompleted. First delete or comment out the line that says:
Expand|Select|Wrap|Line Numbers
  1. throw new NotImplementedException();
and change it to this code:


You may note that there isn't a method called uploadingComplete(). You are right. It's time to create one:



And that's it! You can test it now by hitting F5.

Sample project and Changing the Service Reference Address
You can download the sample project here:
http://www.insertalias.com/upload/by...leuploader.zip
But you must remember to change the service reference to the correct url. Here's how to change the service reference address. Expand the folder called Service References in your Silverlight application, and right-click on the one called FileUploadService. Click "Configure Service Reference."


And you should get this dialog:


Change the address to the correct one and click OK. Remember, to find the correct address, run your application and look at the port number on the url by localhost. Change this one to the one that shows up when you run the app.

When you are ready to publish this to a web server, you will want to change the address of the service reference to the permanent address. Publish it first as-is, and navigate to the .asmx file in your browser. Copy the URL, and follow the steps above to change the reference address. Then publish the application again.

You may have to configure IIS to serve Silverlight apps properly, but that is out of the scope of this article.

I hope you enjoyed reading this and found it helpful.

--insertAlias
Article also available on my blog. Check it out!
Dec 20 '08 #1
Share this Article
Share on Google+
7 Comments


KevinADC
Expert 2.5K+
P: 4,059
I found 26 errors in your article. It is poorly written and appears to not work properly.
















OK...... not really. Awesome article. You might consider working for a site that pays for quality articles like that.
Dec 20 '08 #2

Curtis Rutland
Expert 2.5K+
P: 3,256
Thanks Kevin :) I tried to think of a sarcastic way to say that I thought the sarcasm was funny, but I'm far too tired, so I'll just say that I truly appreciate the compliment.
Dec 20 '08 #3

KevinADC
Expert 2.5K+
P: 4,059
I'm curious, how long did it take you to write the article? I know you will have to make a guess, but I am just curious, a ball park figure if possible and if you wish to say.
Dec 20 '08 #4

Curtis Rutland
Expert 2.5K+
P: 3,256
No guess required. If you only count the writing time, not the coding, about 3.5-4 hours. I made a lot of screenshots. If you do count the time it took to write the project first, probably about 10 hours.
Dec 20 '08 #5

KevinADC
Expert 2.5K+
P: 4,059
I would have guessed higher. I would count the time from start to finish, which would include graphics and code and editing. 10 hours is very fast for an article of that length and quality. Superb job.
Dec 20 '08 #6

Curtis Rutland
Expert 2.5K+
P: 3,256
I've moved this to the insights area. I can't believe I let it sit in editors corner for so long.
Jun 16 '09 #7

Frinavale
Expert Mod 5K+
P: 9,731
Before you try to install SilverLight you're going to have to first install Service Pack 1 for Visual Studio.

You can find this service pack here.
Jun 16 '09 #8