Mastering Binary Data Uploads with Silverlight 2b2

When working with Silverlight 2b2, developers often encounter challenges while trying to upload files or streams of binary data to a web server. Commonly used methods like WebClient and WebRequest may seem simple but can lead to frustrating limitations, such as inadequate notifications for asynchronous uploads and UI blocking issues. This blog post aims to outline these challenges and provide a robust solution to handle binary data uploads effectively.

The Challenges of Uploading Binary Data

Insufficient Progress Notifications

Both WebClient and WebRequest have their shortcomings when it comes to notifying you about the upload progress and completion:

  • WebClient: While it is easy to implement, it lacks the necessary callbacks during the upload process. The asynchronous upload events, such as UploadProgressChanged, often return limited information, and there’s no event to signal when a process has completed successfully.
  • WebRequest: This method is more complicated, involving multiple asynchronous calls. However, many developers report it still seems to block the UI, leading to a poor user experience.

Memory Management Issues

For large files, encoding binary data into a string format to use UploadStringAsync is a typical workaround. Unfortunately, this method can consume vast amounts of RAM, making it impractical for larger uploads due to memory constraints.

A Solution for Smooth Uploads

To overcome these challenges, we can employ a few programming strategies, particularly using the INotifyPropertyChanged interface, which provides an effective way to handle property change notifications in Silverlight. Here’s how you can implement this approach step-by-step:

Step 1: Start the Upload Process

When initiating the upload, first, you’ll want to update your UI state to reflect that the upload is in progress. You can do this by creating a method like DoIt():

public void DoIt(){
    this.IsUploading = True;    
    WebRequest postRequest = WebRequest.Create(new Uri(ServiceURL));
    postRequest.BeginGetRequestStream(new AsyncCallback(RequestOpened), postRequest);
}

Step 2: Open the Request Stream

Next, handle the request using an asynchronous callback. This method prepares the request to send data to your server:

private void RequestOpened(IAsyncResult result){
    WebRequest req = result.AsyncState as WebRequest;
    req.BeginGetResponse(new AsyncCallback(GetResponse), req);
}

Step 3: Process the Response

After the upload has been initiated, you need to process the server’s response. This allows you to gather any feedback or data needed once the upload is complete:

private void GetResponse(IAsyncResult result) {
    WebRequest req = result.AsyncState as WebRequest;
    string serverresult = string.Empty;
    WebResponse postResponse = req.EndGetResponse(result);
    
    StreamReader responseReader = new StreamReader(postResponse.GetResponseStream());
    // Handle response if necessary
    this.IsUploading = False;
}

Step 4: Updating UI Responsiveness

To further enhance the user experience, it’s essential to manage the UI state. Implement a property that signals whether or not the uploading process is ongoing:

private Bool _IsUploading;
public Bool IsUploading {
    get { return _IsUploading; }
    private set {
        _IsUploading = value;
        OnPropertyChanged("IsUploading");
    }
}

Conclusion

By following the outlined steps, you can effectively manage binary data uploads in Silverlight 2b2 without overwhelming your application’s memory or blocking the UI. This method not only enhances the user experience but also provides the necessary feedback during the upload process, addressing many common issues faced by developers.

If you’ve struggled with uploading binary data in Silverlight 2b2, using INotifyPropertyChanged along with proper asynchronous handling can make your development process smoother and more efficient. Happy coding!