The Silverlight Upload Control... Yes, we have one! While it is installed with every DXperience Silverlight subscription, it usually does not get the publicity it deserves. So to set that straight, I decided to prepare this blog post as a means of introduction as well as a guide to get started using the control.
The DevExpress Upload Control for Silverlight isn’t simply a text box that can accept a local file path and upload it to the server. It provides a number of advanced features, such as:
- Uploading multiple files
- Specifying the maximum number of simultaneous uploads
- Specifying the maximum file size
- File Filters
- And more...
This blog post will serve as a tutorial on how to get started using the DXUpload Control for Silverlight. If you like to see this in action or follow along interactively, then a video tutorial will be made available tomorrow, so keep an eyes out on my blog for the announcement.
To start, I’ll need a new Silverlight application project. The first thing I would do is of course add the Silverlight Upload Control to the page. The XAML looks like this:
- <UserControl x:Class="SLUploadControl.MainPage"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- mc:Ignorable="d"
- d:DesignHeight="300" d:DesignWidth="400"
- xmlns:dxco="http://schemas.devexpress.com/winfx/2008/xaml/controls">
-
- <Grid x:Name="LayoutRoot" Background="White">
- <dxco:UploadControl x:Name="uploadControl" />
- </Grid>
- </UserControl>
So far so good. Now, I need to add a new Generic Handler to the web project so files can be uploaded and saved to the server:

As I’ll be working with files, the first thing I’ll add to the new handler is the following namespace:
Next, I’ll remove the existing code and populate it with the following:
- string FilePath { get; set; }
- string FileName { get; set; }
- int PackageCount { get; set; }
- int PackageNumber { get; set; }
- public bool IsReusable { get { return false; } }
-
- public void ProcessRequest(HttpContext context)
- {
- ProcessQueryString(context);
- ProcessFile(context);
- }
-
- void ProcessQueryString(HttpContext context)
- {
- var query = context.Request.QueryString;
- FilePath = Uri.UnescapeDataString(query["filePath"]);
- FileName = Uri.UnescapeDataString(query["fileName"]);
- PackageCount = int.Parse(query["packageCount"]);
- PackageNumber = int.Parse(query["packageNumber"]);
- }
-
- void ProcessFile(HttpContext context)
- {
- string serverFileName = GetServerPath(context.Server, FilePath, FileName);
- FileMode fileMode = File.Exists(serverFileName) && PackageNumber > 0 ?
- FileMode.Append :
- FileMode.Create;
- using (BinaryReader reader = new BinaryReader(context.Request.InputStream))
- using (BinaryWriter writer = new BinaryWriter(File.Open(serverFileName, fileMode)))
- {
- byte[] buffer = new byte[4096];
- int bytesRead;
- while ((bytesRead = reader.Read(buffer, 0, buffer.Length)) != 0)
- writer.Write(buffer, 0, bytesRead);
- }
- }
-
- string GetServerPath(HttpServerUtility server, string filePath, string fileName)
- {
- return server.MapPath(Path.Combine(filePath, Path.GetFileName(fileName)));
- }
So what happens here? First, I define the properties that I’ll need throughout the application (this includes the file path, the file name, etc…). Next, the IHttpHandler.ProcessRequest method is implemented that will be called every time a new package is received from the client. Next, the ProcessQueryString method takes the query string and breaks it up into the properties we created earlier. Finally, the ProcessFile method reads data from the input stream and writes it to the specified location on the server.
We’re almost done, let’s go back to the XAML Code of the application add a few properties to the Upload Control:
- <dxco:UploadControl WebHandlerUri="http://localhost:54199/UploadHandler.ashx"
- FileUploadCompleted="uploadControl_FileUploadCompleted"
- UploadServerPath="Images"
- x:Name="uploadControl"
- Width="532" />
Notice that to keep this example simple, I’m referencing the handler using a direct URL. As it stands, this will need to be updated every time as the Development Server launches on different ports, but in a production environment, the URL can be set to a physical address.
The UploadServerPath property of course specifies where the uploaded images should be saved on the server. For this purpose, I’ve created an empty “Images” folder in my web application project.
Finally, the FileUploadCompleted event, as its name implies, triggers when the upload has finished. I’ll add the following code to load and display the uploaded image at runtime:
- ...
- using System.Windows.Media.Imaging;
- ...
-
- private void uploadControl_FileUploadCompleted(object sender, DevExpress.Xpf.Controls.UploadItemEventArgs e)
- {
- string path = GetPath(uploadControl.WebHandlerUri,
- uploadControl.UploadServerPath,
- e.ItemInfo.Name);
- ImageSource source = new BitmapImage() { UriSource = new Uri(path) };
- uploadControl.ShowPreviewImage(e.ItemInfo, source);
- }
-
- // Gets the path to the uploaded copy of the image located on the target server.
- string GetPath(Uri uri, string uploadServerPath, string fileName)
- {
- string basePath = uri.Port == -1 ?
- string.Format("{0}://{1}", uri.Scheme, uri.Host) :
- string.Format("{0}://{1}:{2}", uri.Scheme, uri.Host, uri.Port);
- string fullPath = string.Format("{0}/{1}/{2}", basePath, uploadServerPath, fileName);
- return fullPath;
- }
And I’m done! I can run the application and see it in action:

The project for this example is also available on CodeCentral: http://www.devexpress.com/Support/Center/e/E2301.aspx