A Generic JSON Serialization Extension Method Starring DataContractJsonSerializer

Download the sample code for this post. 

In October of 2007 The Gu wrote a ToJSON extension method using the JavaScriptSerializer class.  Since that time the JavaScriptSerializer class has been marked obsolete in favor of DataContractJsonSerializer.  In this post we’ll write an updated ToJSON method to satisfy every JSON extension method fantasy you have.  Quick agenda… the goal is to take a .Net object and convert it in to JSON text which would likely be consumed be a remote client.  Let’s start with the object to convert… an Address class.

using System.Runtime.Serialization;
 
...
 
[DataContract(Name = "Address", Namespace = "")]
public class PersonAddress
{
    [DataMember(Name = "City", Order = 1)]
    public string City { get; set; }
    [DataMember(Name = "Country", Order = 2)]
    public string Country { get; set; }
    [DataMember(Name = "PostalCode", Order = 3)]
    public string PostalCode { get; set; }
    [DataMember(Name = "State", Order = 4)]
    public string State { get; set; }
    [DataMember(Name = "Street", Order = 5)]
    public string Street { get; set; }
}


DataContract
and DataMember attributes provide information to the serialization process of how to structure the data.  It is possible to use the more familiar System.Serializable attribute however the output isn’t nearly as friendly.  More on that later.

The constructor for DataContractJsonSerializer we’re using requires knowledge of the Type of object being serialized to JSON.  For the purposes of this method we’re likely to not know which Type is to be serialized.  Quite often it will be a custom type.  We need our extension method to be more generic… I love .Net…  Here’s the method suitable for such a task:

using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;

...

public static string ToJSON<T>(this T obj)
{
    MemoryStream stream = new MemoryStream();
 
    try
    {
        //serialize data to a stream, then to a JSON string
        DataContractJsonSerializer jsSerializer = new DataContractJsonSerializer(typeof(T));
        jsSerializer.WriteObject(stream, obj);
 
        return Encoding.UTF8.GetString(stream.ToArray());
    }
    finally
    {
        stream.Close();
        stream.Dispose();
    }
}

 

Be sure to reference System.Runtime.Serialization and System.ServiceModel.Web.

Let’s dissect a bit.  DataContractJsonSerializer needs to know the object type.  In our case it’s generic, so we’ll let typeof(T) figure it out for us.  The serializer WriteObject method wants a stream to write the serialization output to for which we’re using a MemoryStream; an easy object for retrieving text from.  And that’s what we do… convert the stream’s byte array into a string; our JSON string.

Let’s run this pup using the following code:

PersonAddress address = new PersonAddress();
address.City = "Newport Beach";
address.Country = "US";
address.PostalCode = "92626";
address.State = "CA";
address.Street = "123 Candyland Way";
 
string json = address.ToJSON();
 
Response.Write(json);


And the results:

{"City":"Newport Beach","Country":"US","PostalCode":"92626","State":"CA","Street":"123 Candyland Way"}

Earlier I mentioned if you used the [Serializable] attribute instead of the [DataContract] attribute your solution would compile and function however your results would come out a bit different.  Here’s the output when using Serializable:

<{"<City>k__BackingField":"Newport Beach","<Country>k__BackingField":"US","<PostalCode>k__BackingField":"92626","<State>k__BackingField":"CA","<Street>k__BackingField":"123 Candyland Way"}>

As you can see this is far less friendly to work with from a JSON consumer perspective… Make it easier on yourself and stick with DataContract in this case.

I hope this helps in your JSON endeavors.  Let me know if you have any questions of problems!

Download the sample code for this post.

kick it on DotNetKicks.com
Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Related posts

Comments

January 7. 2008 09:44 AM

trackback

Trackback from DotNetKicks.com

A Generic JSON Serialization Extension Method Starring DataContractJso

DotNetKicks.com

May 31. 2008 07:04 AM

pingback

Pingback from linqtolife.wordpress.com

JSON ile SerileÅŸtirme ve Ters SerileÅŸtirme « LINQ to Life

linqtolife.wordpress.com

June 15. 2008 04:04 AM

pingback

Pingback from linqtolife.wordpress.com

JSON ile SerileÅŸtirme ve Ters SerileÅŸtirme « LINQ to Life

linqtolife.wordpress.com

July 10. 2008 03:30 AM

Raju


Thsnks for your article. I need help from you that is " I am working on JSON + WCF but we are able to work with GET method and primitive types (int, string..) but when we are trying to pass array(int[], etc..) or objects as query string facing the problem"

Could you please suggest a soution to solve this?

Thanks in advance.

Raju

August 7. 2008 05:43 PM

Ross Faneuf

I would like to download your sample code,but the download is blocked. Is it possible to unblock it? Or email the .zip file?

Thanks in advance
Ross

Ross Faneuf

August 8. 2008 12:24 AM

Ian Suttle

Looks like my web host installed some new security feature and didn't communicate that to me. The download now works. Sorry for the trouble!

Ian Suttle

Add comment


(Will show your Gravatar icon)  

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

November 20. 2008 02:17 PM