Silverlight and JSON

Michael Schwarz on Friday, June 1, 2007

Silverlight 1.1 [1] comes with an built-in JSON serializer which can serialize common data types like string, numbers and arrays. It includes a object serializer, too, I think it is nearly the same as in ASP.NET AJAX or Ajax.NET Professional.

I modified my IsolatedStorage [2] demo and added a new method called GetFiles(string pattern) which will return an array of string containing the file names in the storage. Because I already did the managed JavaScript (DLR) demo [2] in on of my earlier posts I'm now using C# (I love Silverlight, I can choose my favorite language all the time).

<pre class="csharpcode"><span class="kwrd">namespace</span> IsolatedStorage { [Scriptable] <span class="kwrd">public</span> <span class="kwrd">class</span> Storage { [Scriptable] <span class="kwrd">public</span> <span class="kwrd">string</span> GetFiles(<span class="kwrd">string</span> pattern) { <span class="kwrd">using</span> (IsolatedStorageFile isf = <br> IsolatedStorageFile.GetUserStoreForApplication()) { JavaScriptSerializer jss = <span class="kwrd">new</span> JavaScriptSerializer(); <span class="kwrd">return</span> jss.Serialize(isf.GetFileNames(<span class="str">"."</span>)); } }

[Scriptable] <span class="kwrd">public</span> <span class="kwrd">bool</span> WriteText(<span class="kwrd">string</span> filename, <span class="kwrd">string</span> s) { <span class="kwrd">try</span> { <span class="kwrd">using</span> (IsolatedStorageFile isf = <br> IsolatedStorageFile.GetUserStoreForApplication()) { <span class="kwrd">using</span> (IsolatedStorageFileStream fsm = <br> <span class="kwrd">new</span> IsolatedStorageFileStream(filename, <br> FileMode.OpenOrCreate, isf)) { <span class="kwrd">using</span> (StreamWriter sw = <span class="kwrd">new</span> StreamWriter(fsm)) { sw.Write(s); } } } } <span class="kwrd">catch</span> (Exception) { <span class="kwrd">return</span> <span class="kwrd">false</span>; }

<span class="kwrd">return</span> <span class="kwrd">true</span>; }

[Scriptable] <span class="kwrd">public</span> <span class="kwrd">string</span> ReadText(<span class="kwrd">string</span> filename) { <span class="kwrd">try</span> { <span class="kwrd">using</span> (IsolatedStorageFile isf = <br> IsolatedStorageFile.GetUserStoreForApplication()) { <span class="kwrd">using</span> (IsolatedStorageFileStream fsm = <span class="kwrd">new</span> <br> IsolatedStorageFileStream(filename, <br> FileMode.Open, isf)) { <span class="kwrd">using</span> (StreamReader sr = <span class="kwrd">new</span> StreamReader(fsm)) { <span class="kwrd">return</span> sr.ReadToEnd(); } } } } <span class="kwrd">catch</span> (Exception) { <span class="kwrd">return</span> <span class="kwrd">null</span>; } } } } </pre>

Because Silverlight (or the Scriptable methods) don't support more complex data types until now (I hope this will change in future releases) we have to return a JSON string that will be parsed on the client-side JavaScript later.

The JavaScriptSerializer is included in the namespace System.Windows.Browser.Serialization. You have to create a new instance of the JavaScriptSerializer class and call the Serialize method which you pass the .NET object you want to serialize. In our example it is a string array we get as result of the IsolatedStorageFile.GetFiles method.

On the client-side JavaScript code I use the eval statement, hm, is not the best way to parse JSON, but the easiest. Of course you can use the ASP.NET AJAX parser or the JavaScript parser at [3]:

<pre class="csharpcode">var control = document.getElementById(<span class="str">"SilverlightControl"</span>);<br>var storage = control.Content.Storage;

<span class="rem">// save any data to the storage</span> alert(storage.WriteText(<span class="str">"test2.txt"</span>, <span class="str">"Hello World!"</span>));

<span class="rem">// read data from the storage</span> alert(storage.ReadText(<span class="str">"test2.txt"</span>));

<span class="rem">// get all filenames in storage</span> var files; eval(<span class="str">"files = "</span> + storage.GetFiles(<span class="str">"."</span>)); <span class="rem">// eval parse JSON</span> alert(<span class="str">"Files: "</span> + files.join(<span class="str">","</span>));</pre>

You can download this example here [4]. For those of you don't have Visual Studio Orcas installed I have included the binary files, too. So, simple double click on the TestPage.html. If you run the example you will see three message boxes: the first will display true if writing was sucessful, the second one will display the content of the file specified in the argument. The last message box will display all filenames in the storage.