From Non-Local Servers Asynchronously
This issue has come up several times for me. That is, you have an image url you want to display in your silverlight .net 1.1 application that comes from some foreign server. That is, you want this to work: (and of course
it does not).
Even though, you can do this:
There seems to be a subtle difference having to do with cross domain security that I just don’t get but since it’s there, we have to deal with it.
So first, why do you even care. Why not just do the one that works? Well, the answer is that you want to be able to deal with what happens while an image is being downloaded. My particular problem has to do with what happens when you bring up a picture in a modal dialog type thing. That is, you click on a small thumbnail, and a larger ones comes up. In my case, I’m getting the image url from a web service so I don’t have the luxury of opening it locally. I have to use a foreign (remote) url. And, the reason I don’t want to open it by simply setting the source tag is that I’m
reusing a control. This means that I’m simply hiding it and unhiding it. If I just set the source and unhide it, the wrong image comes up. That is, the one from the previous request. Then, a few seconds later, the correct image
comes up. Bad.
We really want to use the Downloader object. A very cool control, but not if it doesn’t work cross domain IMHO.
The work around for this is to write a http handler that runs in your local asp.net project that you pass the url you want to display. Then, that web service turns around, calls the cross domain server, gets the image and returns it to your Downloader object. Simple in concept, but the devil is in the details. How, for example to you pass a url (that may include all kinds of stuff like &’s to a local web service. The answer is encode it! Then decode it at the web service. I’m sure you all can whip that up quickly, but since I did already, why bother. I’m going to paste the code below with brief explanations to help. Here goes:
The Silverlight UserControl That Calls the web service
The way I did the code in the silverlight control is to encode the real URL I want. That is the one cross domain. I think build a URL that calls my local web service passing the parameter encoded as a base64 value as one of
the url parameters. I’m using a property in my usercontrol to set this value just because that’s kind of convenient. Here is what the code looks like:
Just to give you a hint of what the might look like, in my case, this is what it is:
(I put a bunch of …’s in the middle, but it was longer than that originally)
Silverlight is kind of limited on conversion functions so I had to write this little one called EncodeTo64 which is pasted below. I’m sure there are better ways to do it, but this one works.
And, don’t forget that you need to have the completed event code in your silverlight side to handle setting the source tag when the image is fully downloaded. Here is that function.
The Http Handler (DisplayImage.ashx file)
To make all this come to live, you need an http handler that will make the call to the cross domain server. Below is that code. I added an extra parameter for width so that if you know the image you need is smaller than the one across the internet, you can just get downloaded what you need. Here is the code for the handler:
I’m guessing that this problem will go away in the next alpha or beta release of Silverlight .net. In the mean time, this works very well for me and hopefully will for you also. I don’t have this in a good sample application and really just wanted to get it posted because I know others were having the same problems. If someone goes through and makes a good demo of this, please post a comment with the code for others to download.
Thanks for reading, and best of luck with your Silverlight Development!