Display Images with the Silverlight Downloader in Alpha 1.1

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).

The Problem

does not work

Even though, you can do this:

does not work

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.

The Solution

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:

does not work

Just to give you a hint of what the might look like, in my case, this is what it is:

http://localhost:49803/WebService/DisplayImage.ashx?URL=aHR0cDov…NDE0NzU2LkpQRw==&Width=400

(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.

does not work

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.

does not work

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:

does not work

 

Conclusion

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!

About Peter Kellner

Follow me:


Comments

  1. I’m not sure the place you are getting your information, however great topic. I must spend some time learning more or understanding more. Thank you for magnificent information I was in search of this info for my mission.

  2. elidea15 says:

    That

  3. all new info,much appreciated,keep it comin’

  4. I’m a student and I never regret the fact that I visit your site.because your site give’s us a lot of idea when it comes to programming.

    Thank you very much for posting this kind topic. you really help a lot of people specially students like me. you give us added knowledge that we may use in the future.

  5. I didn’t like the idea of opening up a proxy on my server, so I’ve worked around this. It turns out that after loading an image through HTML, it’s available like any local resource. This means you can dynamically add a new HTML tag, wait until it’s loaded, then use it in a Silverlight Image. Here’s what it looks like:

    img = System.Windows.Browser.HtmlPage.Document.CreateElement(“img”);

    System.Windows.Browser.HtmlPage.Document.Body.AppendChild(img);

    img.AttachEvent(“onload”, ImageLoaded);
    img.SetStyleAttribute(“visibility”, “hidden”); // hide the
    img.SetAttribute(“height”, “0”); // required
    img.SetAttribute(“width”, “0”); // required
    img.SetAttribute(“id”, “tempdownloader”);
    img.SetAttribute(“src”, “http://hirise-pds.lpl.arizona.edu/PDS/EXTRAS/RDR/TRA/ORB_000800_000899/TRA_000873_1780/TRA_000873_1780_RED.NOMAP.browse.jpg”);

    … and the callback:

    private void ImageLoaded(object source, System.Windows.Browser.HtmlEventArgs e)
    {
    MyImage.SetValue(Image.SourceProperty, (source as HtmlElement).GetAttribute(“src”));
    }

  6. Natasha says:

    I have found two interesting sources and would like to give the benefit of my experience to you.
    I am tuning my pc by the best software for free, with the file search engine http://fileshunt.com and http://filesfinds.com May be you have your own experience and could give some useful sites too. Because this two social sites help me much.

  7. Peter Kellner says:

    Hi Andrew,

    I wish I knew javascript better. I struggled for a long time trying to figure out how to get the data passed and my encoding mechanism does not feel like a good solution, but it does work and it was the best I could come up with. If you write up a better way, I’ll be happy to blog about and point to your solution.

  8. Apologies… it looks like ASP.NET (arguably incorrectly) decodes the amperstand before splitting the variables, so the URL’s variables are split up instead of remaining with the single var.

  9. Why are you inventing your own encoding mechanism? You can use Javascript’s escape() function on the client, and then ASP.NET will automatically decode it (internally using HttpUtility.UrlDecode) for you just by calling Request.QueryString[“somevar”].
    In fact, the encoding done by the escape function is the “right” way to do it according to the URL spec.

  10. That’s a great solution, good job.

    In your opinion should we compensate for the lack of Classes/framework/”Options” in the silverlight CLR by transfering work the server which has an fully-blown .Net CLR & Framework?
    Do you consider this a viable solution?

Trackbacks

  1. […] let’s talk about preloading images. Basically I used something like presented here, but I recommend that you first read the short tutorial on images. A more insightful tutorial on […]

Follow

Get every new post delivered to your Inbox

Join other followers: