After creating Yet Another Photo Gallery, there were some of the things I learned about Silverlight that I wanted to share.
1. Relative URIs in WebClient work. Relative URIs in BitmapImage do not.
If you are downloading data via the WebClient that is from the same website that the Silverlight application is hosted on (note that this is not necessarily the same as the website the webpage that's hosting the application is on), you can specify a relative URI. For example:
WebClient client = new WebClient();
Uri uri = new Uri("../MyPhoto.jpg", UriKind.Relative);
client.OpenReadAsync(uri);
However, if I put the same URI into a BitmapImage, it won't work.
Uri uri = new Uri("../MyPhoto.jpg", UriKind.Relative);
BitmapImage bi = new BitmapImage(uri);
Notice the same actual URI is being used. This is because BitmapImage has some special URI handling to determine if the bitmap is an assembly resource, or packaged in the .XAP file.
An absolute URI will work properly though. But this means that you have to put the full URI in your application and this limits portability.
As a workaround, I do the following:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
Uri uri = new Uri("../MyPhoto.jpg", UriKind.Relative);
WebClient client = new WebClient();
client.OpenReadCompleted +=
new OpenReadCompletedEventHandler(
Download_OpenReadCompleted);
client.OpenReadAsync(uri);
}
void Download_OpenReadCompleted(object sender,
OpenReadCompletedEventArgs e)
{
if (e.Error != null)
return;
// Put the resulting stream in the image
Stream s = e.Result;
BitmapImage bi = new BitmapImage();
bi.SetSource(s);
}
This also gives you the benefit of adding download progress meter as well.
2. The Silverlight test web application created isn't a full web application.
As part of my application, I wanted to add some more advanced functionality, like Xml serialization, to the web application. So in my handler that the Silverlight application calls, I added some System.Xml calls.
These failed because System.Xml.dll could not be found. I do not know what the problem was.
My work around was to create a new web application to replace the stub one that VS2008 created for me. I added Silverlight debugging (easy to do from the project properties) and I was away to the races. System.Xml.dll was found correctly.
You'll also notice that the code generated for a "Generic Handler" .ASHX file is different if it's generated for a standard web application and the Silverlight test host application.
Part 2 of the article can be read here.