In the previous post, which talked about the new Web programming model support for SL4, I mentioned that the support for strongly-typed consumption of REST/JSON services wasn't available out of the box. This post will show how to plug additional code to WCF in Silverlight to enable that. It will make it on par with the desktop version of the web programming model, with the exception of the raw programming model (input/return of type System.IO.Stream), which can also be added based on the same principles as the JSON support.
The whole code for this sample can be found here, in the Silverlight Web Services Code Gallery repository (https://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=silverlightws&ReleaseId=4059). I'll only walk through some parts of the sample here, since there is a lot of boilerplate code which would make this post too large if I were to post everything.
The first component required is the WebMessageEncodingBindingElement. As with the desktop, it should support both JSON and XML services, not just one or the other. This implementation simply delegates XML messages to the TextMessageEncodingBindingElement. For JSON messages, incoming messages will be passed on to the stack as raw bytes, so that later (at the formatter), it will decode it using the System.Json classes. The outgoing messages are created as binary raw bytes by the formatter as well, and the encoder simply writes those bytes to the output.
To plug-in the formatter in the pipeline, we can create our own WebHttpBehavior subclass, and override the Get{Request/Reply}ClientFormatter methods. On the request formatter, we can determine based on the RequestFormat property of the [WebGet/WebInvoke] attribute for the operation which formatter to use (the one for JSON, or the default one for XML); on the reply formatter, this information is only known at the time when the response arrives, so we hold on to both formatters (the JSON and the XML ones) in a simple multiplexing formatter:
The JsonClientFormatter uses the DataContractJsonSerializer and the System.Json classes to serialize and deserialize the parameters into / from JSON. Below is a snippet of the implementation of the DeserializeReply method. It's not the most efficient way to implement it, but it's simple enough that it shouldn't be a huge bottleneck for most applications.
As mentioned in the beginning of this post, the full implementation can be found at the Code Gallery. Let us know if you think this is useful, depending on the number of responses we will consider including support out-of-the-box for JSON in a future Silverlight release.