Dynamic Silverlight Part 2: Managed JScript and flickr
In part 1 of this series, we looked at how to build a simple Hello, World application using Dynamic Silverlight and IronRuby. In this part we're going to build a more sophisticated application using Managed JScript, IronPython, Silverlight 2, and the flickr API. It lets you find the most interesting 5 photos for your search term using the flickr api:
Let's start by walking through an existing JScript app that knows how to display flickr photos on the screen. Download the source code for this tutorial from here:
Open a command prompt, navigate to the demos\flickr_start directory and startup the application using Chiron:
Let's look inside of app.xap, which was generated by Chiron:
You'll see that the assemblies for managed JScript, and Dynamic Silverlight (DSL) are in the xap, along with some Silverlight controls assemblies from the Silverlight SDK. The complete list of assemblies can be found in AppManifest.xaml:
Notice that there is also an assembly called contract.dll - more on this assembly later.
This is a Managed JScript application, and execution begins in app.js.
In Silverlight 1.0 applications, you modified an existing scene by injecting XAML strings, much like how you would use innerHTML in the HTML DOM. In the next part of this tutorial, I will show you how you can do the same thing using just code (and it turns out to be considerably harder than just injecting strings).
The initial scene is defined by app.xaml:
This file shows off some cool new Silverlight 2 features. First, notice the two XML namespaces. The c and e namespace prefixes are mapped to types in the System.Windows.Controls, and System.Windows.Controls.Extended assemblies. These assemblies contain our new Silverlight Controls, which are available as part of the Silverlight SDK.
I'm also really pleased to see that we're releasing the source code for these controls under the Microsoft Limited Public License, as well as the test harness that Shawn's team uses to test these controls. Awesome. We're moving in the right direction folks, and we're not done yet.

As you can see, we're using two simple controls: the WatermarkedTextBox (which makes it trivial to create a Search textbox a'la the search widget in all modern web browser), and the venerable Button.
Let's look at the code in app.js to see what happens when you click on the Search button:
We bind a JScript anonymous method to the search_button control's click event using a familiar (to C# developers) delegate-style binding syntax. Notice how we're also using a JScript closure to bind to the App instance and the application's root visual.
There's a bit of magic going on in scene.search_text.Text. Here, we're using a DLR feature called member injectors, to dynamically inject attributes onto the scene object. Next, let's look at how we generate our flickr query:
Here, we initiate an asynchronous REST all to flickr. QUERY contains a scary flickr REST string that we'll append our search term to. Notice how we again use an anonymous JScript method which functions as a closure to perform an action when the download is complete.
The OpenReadAsync method returns a .NET Stream object which we can pass to Silverlight's built-in JSON serializer. This is where the fun begins :)
The original version of this application was written in IronRuby, and I didn't have a working JSON deserializer handy. While Managed JScript can certainly use any of the widely available JavaScript JSON serialization libraries, I didn't have this luxury in IronRuby. Instead, I used the built-in Silverlight JSON serializer. Unfortunately, this API is designed to be used from statically typed languages. Once we finish implementing the Ruby language, we'll be able to use an off-the-shelf Ruby JSON serialization library. For the time being, however, let me describe the hack that lets you use the Silverlight JSON serializer from a dynamic language.
The inject_photo_list method creates an instance of the JSON serializer, and passes the QueryResults CLR type to its constructor. It then dots into QueryResults to retrieve the properties that we need to retrieve images from flickr.
But where did QueryResults come from? At the top of the file, you'll see this call:
Recall that we had a reference to contract.dll in AppManifest.xaml. This assembly contains the static definition of the JSON result set from flickr. The source for contract.cs can be found in lib\contract.cs. You'll also find a build script that shows how to compile an assembly for Silverlight, assuming that the paths to the Silverlight SDK line up.
The get_photo_url method generates the url that we'll use to get each photo, and you can see how easily we can consume the C# type definitions from Managed JScript:
Finally, we generate the XAML for the photo in the BouncePhoto function:
Can anyone spot the grotesque hack in this example? This hack will be fixed in the next part of the tutorial. For the time being, however, it works :)
Mixing in a little Norvig
If you look carefully at the screenshot of the completed app, you'll notice that the app suggested another spelling for 'howse'. That suggestion was courtesy of Peter Norvig's awesome naive spell checker. Here it is in its entirety (just 21 lines of Python 2.5 code):
Wouldn't it be awesome if we could just use this code from our Managed JScript application? Let's take a look at what we need to do to make it happen.
First, we must add a reference to the IronPython assemblies to our AppManifest:
Next, we'll need to download Peter's code, as well as big.txt, which is a 6MB 'training file' containing about a million words that is used to train the spelling corrector. Both of these files will be added to our app directory, which means that they will be downloaded within the XAP file:
You might be wondering why we didn't just download big.txt from the web. I chose not to because I didn't want to modify Peter's code at all. Files that are downloaded as part of the XAP can be read using the standard IronPython file I/O libraries.
Next, let's look at what we need to do to access IronPython code from Managed JScript:
This code loads the managed spell.py module and stores a reference to the correct method. That method is invoked in the spell_check method, which also generates the UI for the suggestion:
Managed JScript has very nice cross-language integration, which only requires loading the module and invoking it.
Summary
We took a look at Managed JScript as a language that you can use to write Silverlight apps in the browser. You can access the Silverlight libraries, as well as a custom C# assembly that contained the types we used in the Silverlight JSON serializer. Finally, we saw a nice example of integrating a piece of code directly off the Internet, written in a different language (Python) into your Dynamic Silverlight app.
In the next part of this series, we'll take a look at integrating our application with ASP.NET MVC, and switching the language back to IronRuby on the client.
Very nice. I went through some of the lab version (in Ruby) earlier today, but this is a nice enhancement. I can't wait to see the whole show tomorrow.
Posted by: Andy Norris | March 06, 2008 at 11:19 PM
Since when does ECMAScript have overloaded += to add event handlers to callsites? Is this a Managed JScript proprietary feature?
Posted by: RichB | March 07, 2008 at 12:14 AM
Very cool. I'm a bit confused by your (their) usage of the Ms-LPL though. That license says I can ship their binaries with my app, but 3(F) says that it "extend[s] only to the software or derivative works that you create that run on a Microsoft Windows operating system product."
OK, I build my app on Windows using Silverlight, include it in my web site, and now some Linux user surfs to my site and uses the app through Moonlight (same problem with Silverlight on Mac).
Is this a license violation? My app runs on Windows, but without any extra effort on my side, it also runs on Linux and OS X.
If it is a violation, who is the violator?
Posted by: Stefan Wenig | March 07, 2008 at 12:49 AM
@RichB: This is an Managed JScript proprietary feature.
@Stefan: We're working on this :)
Posted by: John Lam | March 07, 2008 at 05:34 AM
Hello John,
Thanks for these cool examples. I'm trying to adapt them for IronPython - having some of the text examples as images makes that more painful though!
Michael
Posted by: Michael Foord | March 09, 2008 at 02:10 PM
@Michael: that's why I have a download link for all the sources at the top of the blog entry :)
Posted by: John Lam | March 09, 2008 at 04:00 PM
Any clue how to use the fancy new controls from *code* rather than XAML? I'm using IronPython and can load controls from XAML (with the appropriate manifest and namespace declarations), but can't import them...
Posted by: Michael Foord | March 09, 2008 at 05:24 PM
I saw one photography search engine with free photos from Flickr.
Please check this link
http://rotavacx.com
It can help you more than most sites because it has some cool visual search tools. You’ll find what you need in seconds.
Posted by: Adam | August 05, 2008 at 03:39 AM
Hi,
Great example. I'm having some problems using build.cmd to compile my own c# assembly. Could you provide instructions?
Posted by: mike | August 18, 2008 at 01:36 AM
Does anyone know - is it posssible to redistribute chiron as part of a xaml/xap authoring application? Does anyone know what licence chiron.exe falls under?
Thanks
Steve
Posted by: Steve Bennett | October 08, 2008 at 05:06 AM