24 November, 2010

WP7: How to consume JSON data on a Windows Phone 7 application

Having witnessed the small footprint of JSON compared to SOAP, I’ve begun taking a real liking in using JSON formatted WCF-services. On top of that, I in particular like the fact that you are actually able to “map” the fields coming from the JSON formatted string into a local object representation using the DataContract attribute in a way I never thought of. Well – here goes.


Server side: This is the JSON formatted data what is received from the WCF service:


[{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"},{"BirthYear":1900,"FirstName":"Anders","LastName":"And"}]

This is just a simple name-value array of strings. See this post for info on how to enable this JSON formatting: http://blog.clauskonrad.net/2010/11/how-to-expose-json-endpoint-from-wcf.html.


And see this post on how to call out to the WCF service from the WP7 application: http://blog.clauskonrad.net/2010/11/wp7-how-to-make-httprequests-from.html


Client side: Now – to convert this string into a local object representation, you can use the DataContract attributes in a real clever way. Notice how the “objects” coming out of the JSON string supposedly suggest this structure:

public class MyClass
{
public int BirthYear { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}


But – what if I want a different set of properties and a completely different class name?



This is where the DataContract kicks in to help out! Using this class, you can actually map this JSON string into your own object construction at will. You start by declaring your own local representation (MyPersonClass) and decorating this with Name=’JSON-field name’. In this way – the DataContractJsonSerializer will handle the mapping.

[DataContract]
public class MyPersonClass
{
[DataMember(Name="BirthYear")] //mapping: BirthYear -> BornYear
public int BornYear { get; set; }

[DataMember(Name = "FirstName")] //mapping: FirstName -> Name
public string Name { get; set; }

[DataMember(Name = "LastName")] //mapping: LastName -> SurName
public string SurName { get; set; }
}


To actually perform the deserialization, you simply go:

//load into memory stream
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
{
//parse into jsonser
var ser = new DataContractJsonSerializer(typeof(MyPersonClass[]));
MyPersonClass[] obj = (MyPersonClass[])ser.ReadObject(ms);
}


This leaves you with an array of ‘MyPersonClass’ objects coming out of the JSON string! Pretty sweet functionality!



Technorati Tags: ,,

7 comments:

Munish Bhargav said...

Thanks

Morten said...

Hey - It seems DataContractJsonSerializer is not part of System.Runtime.Serialization dll in the WP7 assemblies. What am I missing? -- Thanks in advance, Morten

Morten said...

Obviously I was missing out a reference to System.ServiceModel.Web. Sorry :)

Anonymous said...

[DataMember(Name = "LastYear")] ->
[DataMember(Name = "LastName")]

Claus Konrad said...

thx.

ddevine said...

Note that XML can be deserialised by pretty much the same method (obviously not with the JSON functions).
I wish I knew that earlier!

Unknown said...

i m getting error that

Error 1 The name 'Encoding' does not exist in the current context

Error 2 The name 'jsonString' does not exist in the current context

what to do
plzz help