Silverlight File Upload Component

This Silverlight File Upload component will help you build a UI with File Upload capability with the minimum amount of coding, the example we have on this page uses the Progress Bar control to give you a visual representation of the upload progress though as the File Upload is a separate component you can implement any UI you like for it.

To use the File Upload Component you will need to add a reference to Liquid.Components.dll in your project.

How to Use the File Upload Component

To demonstrate the File Upload component we will build a simple upload page containing a Progress Bar and a file browse button, the browse dialog is a standard Silverlight dialog and allows the user to select 1 or many files. In your Silverlight XAML:

<UserControl x:Class="FileUpload.Page"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:liquid="clr-namespace:Liquid;assembly=Liquid"
    Width="400" Height="300">
     <Canvas>
          <liquid:ProgressBarPlus x:Name="progress" Canvas.Left="8" Canvas.Top="8" Width="200" Height="24" />
          <Button x:Name="startUpload" Canvas.Left="80" Canvas.Top="50" Content="Upload" Width="60" Height="32" Click="StartUpload_Click" />
     </Canvas>
</UserControl>
 

In your C# code behind file you will actually get to use the Upload component to upload the selected files and to maintain the progress bar with the upload progress.

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Browser;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Liquid;
using Liquid.Components;
namespace FileUpload
{
     public partial class Page : UserControl
     {
          private Uploader _uploader = new Uploader("http://localhost/vectorlight/FileUploadService.asmx");
          public Page()
          {
               InitializeComponent();
               _uploader.UploadProgressChange += new UploadEventHandler(Uploader_UploadProgressChange);
               _uploader.UploadFinished += new UploadEventHandler(Uploader_UploadFinished);
          }
          private void Uploader_UploadFinished(object sender, UploadEventArgs e)
          {
               progress.Text = "Complete.";
               progress.Complete = e.Progress;
          }
          private void Uploader_UploadProgressChange(object sender, UploadEventArgs e)
          {
               progress.Text = "Uploading " + Math.Round(e.Progress) + "% (" + e.Text + ")";
               progress.Complete = e.Progress;
          }
          private void StartUpload_Click(object sender, RoutedEventArgs e)
          {
               OpenFileDialog dialog = new OpenFileDialog();
               dialog.Filter = "Image files (*.gif;*.jpg;*.png)|*.gif;*.jpg;*.png";
               dialog.Multiselect = true;
               if (dialog.ShowDialog() == true)
               {
                    _uploader.UploadFiles(dialog.Files, "documents/", true);
               }
          }
     }
}
 

In the example above we are handling the button Click event to display the local file browse dialog. When the user selects a file(s) we pass the selected file list property to the File Upload component which does the rest of the work for you.

The method Uploader_UploadProgressChange is called each time a portion of a file has been uploaded, the portion sizes are specified in the File Upload component using the PacketSize property (the default is 32768 or 32KB).

Receiving the File on the Server

The File Upload component uses a web service to push the data over to the server and your receiving web server must have a web service in order to receive the data. Below is an example of typical web service that could handle this:

using System;
using System.Collections;
using System.IO;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
// <summary>
// Summary description for FileUploadService
//summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class FileUploadService : System.Web.Services.WebService
{
     public FileUploadService()
     {
          //Uncomment the following line if using designed components
          //InitializeComponent();
     }
     [WebMethod]
     public string Upload(string mode, string path, string name, string filedata, bool overwrite)
     {
          string filename = string.Empty;
          try
          {
               filename = Server.MapPath("~") + @"\" + path.Replace("/", @"\") + name;
               if (mode == "new")
               {
                    if (File.Exists(filename) == true)
                    {
                         if (overwrite)
                         {
                              File.Delete(filename);
                         }
                         else
                         {
                              return "File Already Exists";
                         }
                    }
                    WriteFile(filename, Convert.FromBase64String(filedata), FileMode.Create);
               }
               else
               {
                    WriteFile(filename, Convert.FromBase64String(filedata), FileMode.Append);
               }
          }
          catch (Exception ex)
          {
               File.Delete(filename);
               return "File Write Error: " + ex.Message;
          }
          return "ok";
     }
     private void WriteFile(string filename, byte[] content, FileMode fileMode)
     {
          Stream target = null;
          BinaryWriter writer = null;
          try
          {
               target = File.Open(filename, fileMode);
               writer = new BinaryWriter(target);
               writer.Write(content);
          }
          catch (Exception ex)
          {
               throw new Exception("Could not write to file: " + filename + " - " + ex.Message);
          }
          finally
          {
               if (target != null)
               {
                    target.Close();
               }
               if (writer != null)
               {
                    writer.Close();
               }
          }
     }
}
 

Your Comments and Questions Answered

 You are not logged in. You need to login to post new messages, if you do not have a login you can register for free!

dan said:

Hi xkrja,

Not being a PHP expert I couldn't say other than all you need on the server is a web service so if PHP can do them then you should be able to convert the provided C# to PHP. Thanks!

06/19/2009 11:24
 
dan said:

Hi karnqu,

You are right, the error handling is a bit lacking at the moment and is something which I'm looking to enhance in the future versions. Thanks!

06/19/2009 11:23
 
dan said:

Hi Paul,

You can implement this easily in your Uploader_UploadProgressChange event handler by simply checking the value of e.Progress == 100 and calling your completion web service there.

Your 2nd point is a good suggestion and one which I will look to implement in the next version. Thanks!

06/19/2009 11:22
 
xkrja said:

Nice control. Would it be possible to use this control with php?

06/16/2009 12:01
 
karnqu said:

Very useful control, how do you notify the Silverlight app of errors when writing the file on the server? Seems like there should be a way to access the results from the server (normally "ok" but could be a stack trace or something).

Currently even with failure the UploadFinished event fires and says progress is 100.

Thanks,
jake

06/15/2009 08:40
 
Paul Carter said:

Hi, thanks for this component, It's proved to be quite useful. There are a couple of other things that would be quite a useful addition. As the files are written to the server in multiple chunks, it would be good to know when the entire file has finished uploading, maybe by your component calling a completion method in the same web service we provide you with.

The last thing is would there be any possibility of being able to send up a soap header or an extra "user data" parameter that would allow some people to associate uploaded files with a certain customer for example?

06/09/2009 08:56
 
Paul Carter said:

Hi, thanks for this component, It's proved to be quite useful. There are a couple of other things that would be quite a useful addition. As the files are written to the server in multiple chunks, it would be good to know when the entire file has finished uploading, maybe by your component calling a completion method in the same web service we provide you with.

The last thing is would there be any possibility of being able to send up a soap header or an extra "user data" parameter that would allow some people to associate uploaded files with a certain customer for example?

06/09/2009 08:43
 
dan said:

Hi hayedid,

Could you explain in a little more detail what you're trying to achieve here? When you upload a file you have to specify the filename and a path so surely using this you can organize the uploaded files as you need?

05/14/2009 08:18
 
dan said:

Hi hayedid,

This isn't possible in the current implementation, could you not store the path/filename in your database which is unique?

05/14/2009 08:16
 
dan said:

Hi moghaddam,

Using web services the service must return the string "ok" to indicate a section has been successfully received, as you're not using web services I'm not too sure what the equivalent is in the struts framework?

05/14/2009 08:13
 
ynyxsky said:

英文的看不懂啊!!!

05/07/2009 06:13
 
ohs0202 said:

05/05/2009 09:20
 
hayedid said:

This upload tool serves no use if you can't specifically track and name the files. How is everyone else doing this?

Thanks.

05/01/2009 07:55
 
hayedid said:

I got this working to go to a directory (as is done in the sample), but I haven't been able to figure out a way to pass in a parameter such as "strIndex" so that I can upload the file to a database and associate it with a key (that my aspx form already knows).

Any help would be appreciated.

Thank you.

04/23/2009 04:39
 
moghaddam said:

Hi again

The maximum length of base64 string ("filedata") is 43692. Files having small sizes in base64 format ) will be uploaded successfully. But bigger files are truncated.

04/23/2009 04:36
 
moghaddam said:

Hi

I'm using FileUpload in an enterprise project. My users need to upload multiple files simultaneously. Client's browsers are all IE and all have Silverlight installed. My application server is Oracle Application Server (not IIS). Everything is going well except that when I upload a file to server, it gets truncated and I receive only a portion of file. I mean the base64 string that I receive on server side is very smaller than what it should be.

I like to know the internal mechanism used by FileUploader component to upload file, in order to debug my problem. I'm not using webservice to upload my file. The URL provided to FileUploader is just an address of an action (in struts framework).

04/23/2009 04:00
 
dan said:

Hi hayedid,

Thank you for sharing your experiences using these controls. Each component lives in a separate assembly which keeps the size of your ZAP down if you are only using one or two controls. The individual pages for each control has a note at the top which assembly is needed, however I think a separate page with a list of assemblies and controls will help here. Thanks!

04/21/2009 01:23
 
hayedid said:

For any other newbies like me, you will also need to add a reference to Liquid.dll. That is where the ProgressBarPlus is located.

04/15/2009 10:01
 
hayedid said:

I put the Liquid DLLs in one directory and added a reference to that directory from within the project controls and the below error went away (this doesn't seem like a good solution).

Now I'm getting an error that the namespace 'ProgressBarPlus' does not exist in the namespace 'Liquid'. This error is on the following line within the Page.g.gs

internal Liquid.ProgressBarPlus progress;
        
Does anyone have any steps to get this working in a new project?

Thanks.

04/15/2009 09:53
 
hayedid said:

Hi Everyone. I'm a SilverLight newbie and I'm trying to get this file uploader working. I added a "SilverLight Application" as a project attached to my already existing Web Site. Then I put in the above code. I'm getting errors on the following two lines:

xmlns:liquid="clr-namespace:Liquid;assembly=Liquid"
and
<liquid:ProgressBarPlus.....

It seems Visual Studio can't see my assembly.

Error - Assembly 'Liquid' was not found. Verify that you are not missing an assembly reference. Also, verify that your project and all referenced assemblies have been built.

Error - The type 'liquid:ProgressBarPlus' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.

I do have Liquid.Components.Dll as a reference in the project.

Any help would be appreciated.

Thank you.


04/15/2009 01:21
 
dpa said:

Hello,

Is it possible to use the uploader component in silverlight with VB ?
When I use this component with VB
I have an Error -> type Uploader is not defined ?


Project
Add reference Liquid.dll and Liquid.Components in my project

In VB Code

Imports Liquid
Imports Liquid.Components

Partial Public Class ucUpload
     Inherits UserControl

     Private Sub LoadFiles()
         Dim _uploader as Uploader = New Uploader("http://localhost/....")
-> Error in vb type Uploader is not defined ?


With Liquid.Components (intellisence)
I find only
Liquid.Components.Internal
and Liquid.Components.Utility


but not Liquid.Components.Uploader

Thanks!

04/06/2009 07:11
 
progs said:

I sent an e-mail to the support with an example file.

03/16/2009 02:26
 
progs said:

Hello,

after some more tests it seems, that there are only problems with some xlsm files. I don't know why there are this problems with these files. I try to recreate this files and try it again.

03/15/2009 11:54
 
dan said:

Hi progs,

Thanks for the extra information. Have you tried this with other files? Maybe you could email an example file that does not upload correctly to support@vectorlight.net? Thanks!

03/14/2009 05:38
 
progs said:

Hello,

the webservice code ist the same as in the demo. After the first test and damged files I copy the code 1:1, so that I can exlude an error in the webservice code.

I use .NET 3.5 SP1 with Windows XP. On Mondy I will test it on Windows Server 2008, but I think that is not a OS problem. At the moment, I only tested it with the ASP.Net Development Server of Visual Studio and not with IIS. Maybe that's the problem.

The damage Parts of the xlsm File, which Excel remove are the printareas and some formulas. So, that are not things, which are only in the makro files of Excel. I will do some more test with more and differend Excel files on monday at work.

03/14/2009 01:22
 
dan said:

Hi progs,

This is the first report we have had of the upload damaging the files, have you implemented the web service as shown in the example? Maybe you can post a copy of it? Thanks!

03/14/2009 10:11
 
progs said:

Hello,

if I upload an Excel 2007 xlsm (Excel with Makro) file, then the file is damaged. When I try to open them with Excel, Excel must repair the file. Without reparing them manually, I could not connect to them via OleDB. Normal Excel 2007 files (xlsx) work fine. Are there any solutions?

03/13/2009 05:44
 
dannychung said:

Hi dan,
In your sample of Uploader, you use UploadFile function with three parameters. And Upload function of web service with five parameters. Now I use UploadFile with four parameters, but I don't know how to define Upload function of web service to let me to save file with different name.

02/11/2009 05:12
 
dan said:

Hi Danny,

1. The targetFilename is simply passed through to the web service and allows you to save the file with a different name on the server.
2. Not too sure what you mean here, the Uploader doesn't have any mode property, could you explain more?

Thanks!

02/11/2009 11:53
 
dannychung said:

Hi,
     My dll's version is 5.1.7.34201.
     Uploader worked perfect.Now I have some questions.
     I use _Uploader.UploadFile with four parameters.
     1. Could you tell me how to use the thrid parameter 'targetfilename'? Is it used to change file name, when I upload file to server?
     2. How to change the mode in Upload funciton of Web Service?

02/10/2009 11:05
 
dan said:

Hi,

Yes this is true, however the uploader at the moment uses a web service for uploading and therefore any data transmitted has to be base64 encoded. There are other ways to upload and we're looking at alternative solutions at this moment. Thanks!

02/04/2009 12:55
 
e.beckers said:

Great control, however it has 1 big issue.
The file gets posted in multiple packets where each packet contains base64 encoded string
containing a piece of the file. This is going to be real slow for big files (e.g. uploading videos)
Much better would be to upload a byte[] array

02/03/2009 01:41
 
dan said:

Hi daniela,

Can you verify you have the Silverlight Tools for Visual Studio 2008 SP1 installed? The following link will be useful: http://silverlight.net/GetStarted/. Thanks!

01/12/2009 10:20
 
danieladacruz said:

Hello all.
I'm trying to open this example with VS2008 but it says
that the project cannot be open.
The error is: The project type is not supported by this installation.
Can anyone help me?

Thanks.
daniela

01/06/2009 04:10
 
endymion said:

Besides server ACLs and crossdomain.xml, note also that this client code doesn't make use of a proxy, instead Liquid.Components.Comms.Execute() sends direct (async) HTTP POSTs to the asmx using an HttpWebRequest object. Out of the box, a asmx service supports HttpGet, HttpPost, Documentation and HttpSoap locally, but only the HttpSoap protocol on remote. To enable HTTP POST remote access, add the following snippet to your web.config <system.web> section: <webServices><protocols><add name="HttpPost"/></protocols></webServices>. Or use WCF with an extensibility hook. Why not use WCF, it's been out now for a couple of years.

11/30/2008 05:52
 
dan said:

Hi,

Yes, the ASP.NET (Network Service) account needs write/modify rights to the folder. Thanks!

11/29/2008 08:06
 
joywei said:

oh, I found the problem when I write myself upload file control :
that maybe the IIS security

please confirm the IIS User has the right of change and write right.

11/27/2008 12:17
 
joywei said:

By the way, can provide the full sample code of the demo?
the demo provided is only with silverlight client

11/18/2008 12:22
 
joywei said:

Hi dan

I've met the same problem like timbot
I'm sure not the crossdomain because I use a WCF for data in the same website,and it work fine
I don't know why the webservice cann't work.
it's only work in .net appliation server

11/18/2008 12:20
 
joywei said:

Hi dan

I've met the same problem like timbot
I'm sure not the crossdomain because I use a WCF for data in the same website,and it work fine
I don't know why the webservice cann't work.
it's only work in .net appliation server

11/18/2008 12:01
 
saykor said:

This solution is incredible.
Thank you very much

11/16/2008 06:16
 
dan said:

Hi timbot,

There are lots of possible configuration issues here, number one being that the web service URL is identical to the URL your Silverlight app is served from, i.e. does your Silverlight app live at http://flydoc.timbot.net/ClientBin ?

There is also configuration info on the MSDN which may help!

11/06/2008 02:44
 
timbot said:

ok, well, i'm dumb, i figured out what i was doing wrong, i had to add a container to the tab and add my controls and the uploader to that instead...

ok, but now i have a new problem, i've got an uploader working mostly, except nobody can upload remotely, i can upload fine from the local machine, but that does me no good. can anybody help lead me in the right direction? it keeps saying something about an unhandled exception... you can check it out here http://flydoc.timbot.net/Documents/ any help would be most appreciated

11/03/2008 06:33
 
dan said:

Hi timbot,

This should work fine. However, are you adding this component in XAML? I would recommend adding it in C#, please let us know what your XAML declaration tag looks like? Thanks!

10/30/2008 05:07
 
timbot said:

... when i'm trying to use it inside a tab control... (see my last post)

10/29/2008 09:06
 
timbot said:

when i try and add this control to my page i keep getting an error about "The property 'Content' is set more than once"

10/29/2008 08:58
 
chordia said:

Can anyone share a working example VS 2008 project?

I've implemented a simplistic service to save files which works but cannot debug it - it gets as far as calling uploader.upload() then fails with a security exception

I can post my code if anyone is interested.

Thanks

Jerry.

10/21/2008 07:07
 
dan said:

Hi AJ,

Wow, thanks! It's good to see posts like this. It does seem the random port numbers might be causing some people issues with this component. I'm sure there are lots of happy users of these free controls out there. Thanks again!

10/17/2008 11:58
 
ajdyke said:

Hi Everyone,

Just put together a proof-of-concept of the file uploader and wanted to say that it was surprisingly easy to implement and everything is working perfectly! A lot of the comments on here that look like they can't get it to work, so I thought a positive one would be welcome.

I'm using Liquid Controls 5.0, VS2008 on Windows Vista and the release version of Silverlight 2. The code above works with little/no modifications necessary! I created a Silverlight and Website project using the VS templates, set the website project to use a static port instead of dynamic (localhost:8080) so that the web service would always be accessible and voila! Efficient file uploads that just work, fully integrated with Silverlight 2 and ASP.Net 3.5, with full debugging capabilities that allow me to step through both ends of the transaction!

I couldn't be happier!

- AJ

10/17/2008 10:23
 
dan said:

Hi Corrado,

In theory what your doing should work and I'm puzzled as to why it is not. Can you tell me what version of the controls library you are using and also the URL of your Silverlight application and also the URL of your Web Service?

10/16/2008 03:01
 
dan said:

Hi antonin,

Thanks for that, we will look to get your seggestion implemented in a future version of the controls library!

10/16/2008 02:59
 
cbettero said:

Hi,
I have a problem with upload component.

I have the webservice on the same server of the silverlight application;
if I USE the application ON the same server, all goes OK, the progess bar goes 100% and the file gets uploaded.
If I use the site from ANOTHER machine, (open the browser and write the SAME address used on the server) the Upload Dialog is "stuck" at 0%, and the file never gets on the server.
I tried this with all Liquid versions, always the same result.

What I'm doing wrong ?
Thanks..
Corrado

10/10/2008 12:11
 
antonin.jelinek said:

Hello Dan,

thanks for your reply. Actually, file upload works fine in my app now. There were some issues with my code.

However, there is one enhancement you should consider for future releases - enable developers to set destination file name. Right now, this uploader just use filename of selected file to upload but is some solutions (like the one I'm working on), I need to set a system name for uploaded image prior to uploading, so I'd like to have a possibility to set "string name" in Upload webservice method signature.

Thanks,

Antonin

09/02/2008 06:47
 
dan said:

Hi Antonin,

Is your Silverlight app running from http://www.fcbdev.cz/ ? Silverlight is very restrictive and the domain the Silverlight app is running must be the same as the web service you are calling. I am not quite sure how this applies to mappings used IIS. Have you tried the component in a test website on localhost with a simple test Silverlight app?

09/01/2008 10:31
 
antonin.jelinek said:

I have the very same issue as reported by oksi.

Webservice is running on url: http://www.fcbdev.cz/services/UploadImagesService.asmx (please note that this is a local IIS server with 127.0.0.1 www.fcbdev.cz entry in hosts file. Confirmed that WebService is running.) Upload method has this signature:
[WebMethod]
public string Upload(string mode, string path, string name, string filedata, bool overwrite)
{}

When I try upload file(s) from SL, I tried both:

//_uploader.UploadFiles(fdfis, "", true);
_uploader.UploadFile(fdfis[0], "", true);

but both methods seems like not doing anything, events UploadFinished and UploadProgressChange are never hit.

09/01/2008 08:19
 
dan said:

Hi,

Firstly what is the URL of your web service you are calling in your Silverlight application? And what is the URL of you web service when you successfully test it? Also, could you provide the Upload() web service method declaration?

08/02/2008 09:42
 
oksi said:

Hi,

got version 4.8.
Used code from this page, but this line _uploader.UploadFiles(dialog.SelectedFiles, "documents/", true);
never hits the web service.
WEb service is tested, it works fine.
Any idea?

thanks

08/01/2008 05:47
 
dan said:

To andreyk44:

Can you provide more details of the problem you are having, from what I understand you are calling a web service locally (localhost) and that is working fine but on another server it is failing? It may be a symptom of cross-domain calling which is restricted in Silverlight, see http://silverlight.net/forums/t/7448.aspx.

07/01/2008 04:07
 
dan said:

Hello,

Thanks fro pointing this out, we will update this soon, in Silverlight 2 BETA 2 web service call-backs run in a different thread to the main UI and therefore cannot access UI properties. The file upload demo has been updated for BETA 2 and you can also download the example project from this page.

07/01/2008 03:58
 
taazaa said:

Hi,
Has this been updated to Beta 2? I just tried it and the web service never seems to be invoked or returned.

Thanks for your help.

07/01/2008 03:40
 
andreyk44 said:

I get exception System.InvalidOperationException for both versions 4.6 and 4.7 :
"Request format is unrecognized for URL unexpectedly ending in '/Upload'."
It happens only when SV client runs remotely. The same application works fine on localhost.

07/01/2008 06:38
 
dan said:

Hi Paul,

We're updating this demo at the moment. Basically in BETA 2 the Uploaded event handlers are running under a different thread to the main UI which causes problems when trying to set UI element properties (such as progress.Text in the above example) from an event handler.

We'll try to get this updated soon!

06/10/2008 05:07
 
Paul Fretter said:

Anyone tried the file upload under Beta 2? For me it stalls, never returning from the web service call. It was working fine under Beta 1.

Thanks

06/09/2008 11:31
 
dan said:

Hello,

This page has appeared a few days early! Version 4.5 will be out by th 18th May to download along with the demo code.

05/15/2008 12:02
 
esueno said:

This is amazing demo. I tried to download the demo source but he link is dead.
Also I don't see the FileUpload control in 4.4. When will it be released?
Thanks
-sw

05/14/2008 01:33

Silverlight 3

Latest News

  • Silverlight 2 Controls V5.2.1 Released
    Jul, 03 2009

    After several months since the last release we have implemented many fixes to the controls library. The Rich TextBox has been improved with Links...

  • Silverlight 3 BETA Controls Released
    Mar, 30 2009

    As Silverlight 3 BETA is available now to test we thought we would present the Liquid Controls library for Silverlight 3. This BETA...

Silverlight 2 Controls

  • Rich TextBox

    Create and edit rich content with this slick and expandable Rich TextBox...

  • TreeView

    This easy to use TreeView comes with drag and drop, sorting, searching and much more...

  • Context Menu

    You too can have cool popup context menus in your Silverlight applications...

  • Resizable Dialog

    Draggable and resizable popup dialogs are what serious Silverlight developers need...

  • Spell Checker

    Real-time spell checking in Silverlight? We did it first here...