I recently had to find the cause of a puzzling error in the Silverlight 2.0 game I am working on. The game uses Image controls to load pictures returned from Google image search. To load a picture I first create a new Uri object containing the address of the image, then use it to construct a BitmapImage object. I wire up a handler for the BitmapImage.DownloadProgressChanged event, as well as the Image.ImageFailed event, and then set the ImageSource property of the Image control to reference the new BitmapImage. All very straightforward, and it worked fine while I was referencing a test image (.png) located on my local disk (in /Bin/Debug/images).
However, once I got the Google search part working and started to pass http: addresses to my algorithm things went south. Every attempt to load an image failed and invoked my ImageFailed handler with an AG_E_NETWORK_ERROR exception. If you do much Silverlight programming with images I predict you will come to hate this particular error code, and I do hope the dev team replaces it with something more informative. Anyway, this was quite puzzling. I checked the URLs manually and each referenced a valid image that I could pull up in a browser. So what was the problem?
After doing a little research on the Silverlight.net forums user IanBlackburn jumped in and pointed me to a helpful post on URL access restrictions in Silverlight 2. At first glance this didn’t clear up anything for me. The document states that image URLs are allowed to be cross-domain, so that wasn’ t it. A little more discussion and a closer reading and it suddenly dawned on me that while images could be cross-domain, they couldn’t be cross-scheme. What this means is that if your app is located at an http: address, for example, you can’t pull images from an https: address. It also means that if your app is located at a file: address you can’t pull images from an http: address.
Aha. See, when you create a Silverlight project in Visual Studio the default behavior is to create a TestPage.html at /Bin/Debug and embed your component in it. When you run the app to debug it is passed to the browser instance as a file: address pointing to that TestPage. Since my images were out on the net at http: addresses this caused the network error, which was really not a network error at all, but rather a wholly client-side policy-based security denial. Fortunately another default behavior of Visual Studio is to create a test website for the component. If you execute the test website and debug there, then the app is running at an http: address and all is well. So when it comes to accessing network resources, where you test your Silverlight app matters.