Troubleshooting Silverlight File Upload Errors and Fixes

How to Implement Silverlight File Upload: Step-by-Step Guide

Silverlight applications can provide rich client-side experiences, including file uploads to a server. This guide walks through a complete, practical implementation using Silverlight 5, covering client-side selection, validation, progress reporting, and server-side handling (ASP.NET). Example code snippets are included for each step.

Prerequisites

  • Visual Studio (2010–2015 recommended for Silverlight support).
  • Silverlight 5 SDK and developer runtime installed.
  • An ASP.NET Web Application (MVC or WebForms) for server endpoints.
  • Basic familiarity with C#, XAML, and HTTP.

Overview of the approach

  1. Create a Silverlight project and host page.
  2. Add UI for file selection and upload progress.
  3. Use the OpenFileDialog to pick files in Silverlight.
  4. Validate files (size, type) client-side.
  5. Stream the file using WebClient/HttpWebRequest or WCF stream to the server.
  6. Implement server endpoint to receive and store the file.
  7. Report progress and handle errors.

1. Create the Silverlight project and host

  • In Visual Studio, create a new “Silverlight Application”. Choose to host in a new Web Application.
  • Ensure the Web project has an ASP.NET page (Default.aspx) that embeds the Silverlight XAP.

2. Build the UI (XAML)

Add controls: a Button to open file picker, a TextBlock for selected filename, a ProgressBar, and an Upload Button.

xml

<UserControl x:Class=FileUploadSample.MainPage xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml Width=400 Height=140> <StackPanel Margin=10 VerticalAlignment=Top> <Button x:Name=BrowseButton Content=Browse… Width=80 Click=BrowseButton_Click/> <TextBlock x:Name=FileNameText Margin=0,6,0,0/> <ProgressBar x:Name=UploadProgress Height=18 Width=360 Minimum=0 Maximum=100 Margin=0,6,0,0/> <Button x:Name=UploadButton Content=Upload Width=80 Click=UploadButtonClick Margin=0,8,0,0/> <TextBlock x:Name=StatusText Foreground=Red Margin=0,6,0,0/> </StackPanel> </UserControl>

3. Let users pick files (OpenFileDialog)

Use OpenFileDialog to allow selection; access file(s) as StreamResourceInfo or Stream.

csharp

using System.Windows.Controls; using System.Windows; using System.IO; using System.Windows.Resources; private Stream _selectedFileStream; private string _selectedFileName; private void BrowseButton_Click(object sender, RoutedEventArgs e) { var dlg = new OpenFileDialog(); dlg.Filter = “All files (.)|.; dlg.Multiselect = false; if (dlg.ShowDialog() == true) { var file = dlg.File; _selectedFileName = file.Name; FileNameText.Text = _selectedFileName; selectedFileStream = file.OpenRead(); // Stream of selected file StatusText.Text = ””; } }

4. Client-side validation

Check file size and extension before uploading.

csharp

private const int MaxSizeBytes = 10 1024 1024; // 10 MB private bool ValidateSelectedFile() { if (_selectedFileStream == null) { StatusText.Text = “No file selected.”; return false; } if (selectedFileStream.Length > MaxSizeBytes) { StatusText.Text = “File too large (max 10 MB).”; return false; } // optional: validate extension return true; }

5. Uploading the file from Silverlight

Two common approaches: WebClient (multipart/form-data) or HttpWebRequest with chunked streaming. WebClient is simpler but less flexible. Below is a WebClient multipart approach using a MemoryStream to build the multipart content.

csharp

using System.Net; using System.Text; private void UploadButton_Click(object sender, RoutedEventArgs e) { StatusText.Text = ””; if (!ValidateSelectedFile()) return; var client = new WebClient(); client.UploadProgressChanged += Client_UploadProgressChanged; client.UploadStringCompleted += Client_UploadStringCompleted; // Build a multipart/form-data body string boundary = ”—————————” + DateTime.Now.Ticks.ToString(“x”); client.Headers[“Content-Type”] = “multipart/form-data; boundary=” + boundary; var ms = new MemoryStream(); var writer = new StreamWriter(ms); string header = \("--</span><span class="token interpolation-string interpolation" style="color: rgb(57, 58, 52);">{</span><span class="token interpolation-string interpolation expression language-csharp">boundary</span><span class="token interpolation-string interpolation" style="color: rgb(57, 58, 52);">}</span><span class="token interpolation-string" style="color: rgb(163, 21, 21);"> Content-Disposition: form-data; name="file"; filename="</span><span class="token interpolation-string interpolation" style="color: rgb(57, 58, 52);">{</span><span class="token interpolation-string interpolation expression language-csharp">_selectedFileName</span><span class="token interpolation-string interpolation" style="color: rgb(57, 58, 52);">}</span><span class="token interpolation-string" style="color: rgb(163, 21, 21);">" Content-Type: application/octet-stream "</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span> writer</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(57, 58, 52);">Write</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span>header</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span> writer</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(57, 58, 52);">Flush</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span> <span> </span><span class="token" style="color: rgb(0, 128, 0); font-style: italic;">// copy file stream</span><span> </span><span> _selectedFileStream</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span>Position </span><span class="token" style="color: rgb(57, 58, 52);">=</span><span> </span><span class="token" style="color: rgb(54, 172, 170);">0</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span> _selectedFileStream</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(57, 58, 52);">CopyTo</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span>ms</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span> writer</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(57, 58, 52);">Write</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token" style="color: rgb(163, 21, 21);">" "</span><span class="token" style="color: rgb(57, 58, 52);">)</span><span class="token" style="color: rgb(57, 58, 52);">;</span><span> </span><span> writer</span><span class="token" style="color: rgb(57, 58, 52);">.</span><span class="token" style="color: rgb(57, 58, 52);">Write</span><span class="token" style="color: rgb(57, 58, 52);">(</span><span class="token interpolation-string" style="color: rgb(163, 21, 21);">\)”–{boundary}– “); writer.Flush(); ms.Position = 0; var buffer = new byte[ms.Length]; ms.Read(buffer, 0, buffer.Length); // endpoint on server Uri uri = new Uri(HtmlPage.Document.DocumentUri, ”/FileUploadHandler.ashx”); client.UploadDataAsync(uri, “POST”, buffer); }

Progress and completion handlers:

csharp

private void Client_UploadProgressChanged(object sender, UploadProgressChangedEventArgs e) { UploadProgress.Value = e.ProgressPercentage; StatusText.Text = $“Uploading… {e.ProgressPercentage}%”; } private void ClientUploadStringCompleted(object sender, UploadStringCompletedEventArgs e) { if (e.Error != null) { StatusText.Text = “Upload failed: “ + e.Error.Message; return; } StatusText.Text = “Upload complete”; }

Note: UploadDataAsync triggers UploadDataCompleted rather than UploadStringCompleted if using UploadDataAsync; adapt handlers accordingly.

Alternative: HttpWebRequest for chunked or large uploads and for reporting finer-grained progress.

6. Server-side: Receive and save the file (ASP.NET handler)

Create FileUploadHandler.ashx in the web project to accept multipart uploads.

csharp

public class FileUploadHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { try { if (context.Request.Files.Count > 0) { var file = context.Request.Files[0]; string savePath = context.Server.MapPath(”~/UploadedFiles/”); if (!Directory.Exists(savePath)) Directory.CreateDirectory(savePath); string full = Path.Combine(savePath, Path.GetFileName(file.FileName)); file.SaveAs(full); context.Response.StatusCode = 200; context.Response.Write(“OK”); } else { context.Response.StatusCode = 400; context.Response.Write(“No file received”); } } catch (Exception ex) { context.Response.StatusCode = 500; context.Response.Write(“Error: “ + ex.Message); } } public bool IsReusable { get { return false; } } }

For MVC, accept via HttpPostedFileBase in a controller action.

7. Security and robustness tips

  • Validate file type and size on server-side too.
  • Store uploads outside the webroot or sanitize filenames.
  • Scan for malware if appropriate.
  • Use HTTPS to protect data in transit.
  • Implement authentication/authorization if uploads are restricted.
  • For large files, implement chunked uploads and resume support.

8. Large files and advanced scenarios

  • Use HttpWebRequest with BeginGetRequestStream/BeginGetResponse for streaming.
  • Implement chunked uploads: split file into parts client-side and reassemble server-side.
  • Consider WCF streaming for direct streamed calls to services.

Example: Simple HttpWebRequest upload (outline)

  • Create HttpWebRequest to POST to handler.
  • Get request stream asynchronously, write file bytes in chunks, call GetResponse.

(For brevity, code omitted; follow similar patterns as WebClient but managing streams directly.)

9. Testing and debugging

  • Test with various file sizes and types.
  • Use Fiddler or browser dev tools to inspect requests.
  • Log server-side exceptions.
  • Ensure content-length and boundaries are correct in multipart body.

10. Wrap-up

This guide demonstrated creating a Silverlight UI to pick a file, validate it, upload via multipart/form-data to an ASP.NET endpoint, and handle progress and errors. For production, prefer server-side validation, HTTPS, and handling large files via streaming or chunking.

If you want, I can provide a full sample project (client and server) with HttpWebRequest chunked upload and resume support.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *