Saturday, 9 May 2009

Silverlight DataContractJsonSerializer Error

Admittedly there is very little excuse for hand-crafting Json output these days, with libraries like Json.NET available, and WCF supporting Json natively. However, I was tweaking an existing ASPX page (that was actually rendering Xaml for a Silverlight 1.0 application) to turn it into a 'service' for Silverlight 2.0... and it seemed like the fastest way to do that was simply replace a whole pile of <s and >s with {}

I got some hints/reminders on how to Consume a JSON object in Silverlight, and found Jsonlint really helpful in tuning the output until it was valid Json.


Then I created a 'matching' object model in Silverlight C#


and wired up the OpenReadCompleted event using DataContractJsonSerializer


Everything LOOKED like it should work, so at first I was confused by this error message:
Unable to cast object of type 'System.Collections.Generic.List`1[System.Object]' to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]'

After staring blankly at the code for a while, I finally realised where my Json had gone wrong -- at the very root of my Json response (see Jsonlint image above) I was "accidentally" wrapping the entire Json output with an unnecessary [] pair. I guess this meant the Deserializer was expecting to cast into a collection (albeit with a single element), but I was intending the root Json element to be a single object (to match my C# JsonCourse).

The simple fix was removing the enclosing [] so that my Json started off like this instead:
{
"width": 800 ,
"height": 600 ,
"runners": [
{
"name": "mapcanberramarathon",
"points": [
Lesson for tonight is to better understand the underlying Json representation before consuming it (or else use a library rather than hand-craft the output). Anyway now it is fixed RaceReplay.net 2.0 is that much closer to fruition...

No comments:

Post a Comment