Large file uploading using Silverlight, ASP.Net and WCF Part 3

February 25, 2009 22:45 by Rob

Welcome to part 3 of my little series of creating an Asp.net component that allows to upload files of several megabytes without connection timeouts.

In part 1, I explained how the Silverlight component was built and in part 2 the backend service was discussed. In this third and last part I will explain the reusable ASP.Net server control that combines the features into a plug and play component.

The component will solve the following problems:

  • How do I host the SilverLight component?
  • How do I know when the upload has completed?
  • How do I retrieve the contents of the file?

Hosting the SilverLight component

The SilverLightUploader control overrides the CreateChildControls and embeds a System.Web.UI.SilverlightControls.Silverlight component to host the uploader. The control provides for a couple of properties and some are passed on to the silverlight component by providing some initialization parameters. These include:

  • The url of the webservice to be called
  • The location of the SilverLightUpload.xap package.
  • The filter that limits the extension of the files that can be uploaded.

image

I used a helper function to resolve the passed Url’s to absolute url’s because of some limitations I had in my library, but a simple ResolveUrl should be sufficient in most cases.

Also note the OnPluginLoaded hook. This hook is used to bind the event (that is raised when a file is uploaded) to JavaScript.

When a file upload is completed, the Silverlight component raises an event. This event is then catched by a JavaScript block which saves the token of the upload in a hidden field. The Silverlight component just displayed ‘Upload Completed’ and sits and waits until the page is submitted. (the script block is not shown here).

On postback of the page the control checks if the hidden field contains a valid token, and if this is the case, the asp.net component raises an event that can be caught by the page which contains the control.

The control implements IPostBackDataHandler, which means that on any postback the LoadPostData method of the control will be called.

image

The GUID of the upload is persisted in a ViewState-backed property. So even if a validation error occurs on postback, the upload is still safe. (Unfortunately, the Silverlight component does not reflect this yet). LoadPostData returns ‘true’ and the asp.net framework calls RaisePostDataChangedEvent after all the initialisation logic of the page have been completed:

image

 

 

The page that is subscribed to the FileUploadEvent can then call the UploadManager.GetUpload() with the ID that is provided in the event to retrieve the file.

Some tricks left

Instead of putting the SilverlightUpload.xap in /ClientBin, I have embedded the package in the web control by adding it as an embedded resource. I added this file to the project using ‘Add Existing Item’ and ‘Add as Link’ to the SilverlightUpload.xap from the web application. This last step saved me from manually copying the xap every time I created a new build.

image

In AssemblyInfo.cs I have added a declaration so that webresource.axd can be used to retrieve the xap:

image

Also, I moved the implemementation of the WCF UploadService.svc into the control DLL.

Now, to use this control:

  • Add the WebResource.axd handler declaration to the web.config of your web application,
  • Append the service EndPoint to the web.config,
  • Add the SilverlightUpload.dll to the bin directory (or add a reference)
  • Create a file that is a stub for the WCF service (this is the almost-empty UploadService.svc file),
  • Create a page that uses the control,
  • Add an eventhandler to the FileUploaded event

For your uploading pleasure, I’ve added the project with all code to this post.

That should be it!

SilverlightUpload.zip (73.54 kb)


Currently rated 5.0 by 4 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5