(X) Hide this
    • Login
    • Join
      • Generate New Image
        By clicking 'Register' you accept the terms of use .

JSON serialization and deserialization in Silverlight

(9 votes)
Martin Mihaylov
>
Martin Mihaylov
Joined Oct 29, 2007
Articles:   50
Comments:   70
More Articles
12 comments   /   posted on Jul 11, 2008
Categories:   Data Access , General

This article is compatible with the latest version of Silverlight.


Recently I had to work with JSON files and more especially with serialization and deserialization using Silverlight and .NET. The information I found was very limited, so I had to figure it out by myself. When I managed, I decided to write it down for people who would have had the same problems as me.

Introduction

Let’s start with a short introduction of what JSON is. It stays for JavaScript Object Notation and is used as an alternative of the XML. Here is a simple example for a JSON file:

{"FirstName":"Martin","LastName":"Mihaylov"} for a single object

And

[{"FirstName":"Martin","LastName":"Mihaylov"},{"FirstName":"Emil","LastName":"Stoychev"}] for multiple objects.

It looks like an array. Depending on the object that is serialized it could look really complicated.

Serializing

In .Net there is class DataContractJsonSerializer that works great for serializing and deserializing JSON files. To use it you must add a referrence to the System.ServiceModel.Web, although it's in the System.Runtime.Serialization.Json namespace. Before we start with the serialization we have to create a class that can be serialized to JSON. I am going to use a very simple example for this article:

 [DataContract]
 public class Person
 {
     [DataMember]
     public string FirstName { get; set; }
     [DataMember]
     public string LastName { get; set; }
 }

In order to be serializable with DataContractJsonSerializer we have to set a [DataContract] attribute. The properites that will be used by the serialization must have [DataMember] attributes. Note: To use these attributes add a reference to System.Runtime.Serialization;

Now we are ready to begin with the serialization. Let's create a method that takes our object as an argument and returns a string in JSON format:

 public static string SerializeToJsonString( object objectToSerialize )
 {
     using( MemoryStream ms = new MemoryStream() )
     {
         DataContractJsonSerializer serializer =
                 new DataContractJsonSerializer( objectToSerialize.GetType() );
         serializer.WriteObject( ms, objectToSerialize );
         ms.Position = 0;
 
          using( StreamReader reader = new StreamReader( ms ) )
          {
              return reader.ReadToEnd();
          }
      }
  }

We create an object of DataContractJsonSerializer type and in the constructor we set the type that will be serialized. Then using the WriteObject method our object is serialized and written to a stream. After that we use a StreamReader to read the stream and here is our JSON string.

Deserializing

Now let's try to deserialize an object of type Person. We create the following method:

 public static Person DeserializeToPerson( string jsonString )
 {
     using( MemoryStream ms = new MemoryStream( Encoding.Unicode.GetBytes( jsonString ) ) )
     {
         DataContractJsonSerializer serializer =
                 new DataContractJsonSerializer( typeof( Person ) );
 
         return ( Person )serializer.ReadObject( ms );
     }
  }

Here we create a stream from the json string and pass it to the ReadObject method of the serializer. And our object is deserialized.

If you want to deserialize a list of objects it's done the same way:

 public static List<Person> DeserializeToListOfPersons( string jsonString )
 {
     using( MemoryStream ms = new MemoryStream( Encoding.Unicode.GetBytes( jsonString ) ) )
     {
         DataContractJsonSerializer serializer =
                 new DataContractJsonSerializer( typeof( List<Person> ) );
 
         return ( List<Person> )serializer.ReadObject( ms );
     }
  }

The only thing that's different is the type. Here comes the question: Can we have only one method and reuse it independent of the type? Yes, we can using a template method. Here is how the method looks now:

 public static T Deserialize<T>( string jsonString )
 {
     using( MemoryStream ms = new MemoryStream( Encoding.Unicode.GetBytes( jsonString ) ) )
     {
         DataContractJsonSerializer serializer = new DataContractJsonSerializer( typeof( T ) );
 
         return ( T )serializer.ReadObject( ms );
     }
 }
 
"T" is a type argument and we use it to make the method independent of the type. When we call the method, we can specify it:
 
  List<Person> persons = Deserialize<List<Person>>( jsonString )
 
To learn more about that read this article.

Summary

These are the basic things needed to serialize and deserialize object to/from JSON with .NET using DataContractJsonSerializer. So go ahead and find some JSON files to try it!


Subscribe

Comments

  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by Sergei meleshchuk on Aug 20, 2008 10:56

    Cool and clear; Thanks

  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by Bradford on Aug 21, 2008 19:42

    Beautiful - works like a charm. Thank you!

  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by Satya N. on Oct 31, 2008 04:54

    Good stuff.

  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by ad on Apr 02, 2009 08:32
    гавно
  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by Ross Brodskiy on Apr 23, 2009 16:38

    Heres much more organized way of doing the same, plus it give you ability to Serialize and deSerialize into that precise same object! Thats can be important in may instances.Imports System
    Imports System.Xml
    Imports System.Xml.Linq
    Imports System.Collections.Generic
    Imports System.Runtime.Serialization.Json

    Imports System.IO
    Imports System.Text
    Imports System.Runtime.Serialization

    Partial Public Class Serializer
        ''' <summary>
        ''' Takes a MemoryStream and creates string
        ''' </summary>
        ''' <param name="m"></param>
        ''' <returns></returns>
        Public Function GetStringFromMemoryStream(ByVal m As MemoryStream) As String
            If (m Is Nothing) Or m.Length = 0 Then
                Return ""
            End If
            m.Flush()
            m.Position = 0
            Dim UTF8 = UTF8Encoding.UTF8
            Dim sr As New StreamReader(m, UTF8Encoding.UTF8)
            Dim s As String = sr.ReadToEnd()
            Return s
        End Function
        ''' <summary>
        ''' Takes a string and creates MemoryStream
        ''' </summary>
        ''' <param name="s"></param>
        ''' <returns></returns>
        Public Function GetMemoryStreamFromString(ByVal s As String) As MemoryStream
            If (s Is Nothing) Or s.Length = 0 Then
                Return Nothing
            End If
            Dim a = System.Text.Encoding.UTF8.GetBytes(s)
            Dim m As New System.IO.MemoryStream(a, True)
            m.Position = 0
            Return m
        End Function
        ''' <summary>
        ''' JSON Serialize an object into
        ''' </summary>
        ''' <param name="BaseType"></param>
        ''' <returns></returns>
        Public Function Serialize(ByVal BaseType As Object) As String
            Dim ExactName = BaseType.GetType.AssemblyQualifiedName
            Dim Sur As String = p_Serialize(BaseType)
            Dim oList As New List(Of String)
            oList.Add(ExactName)
            oList.Add(Sur)
            Return p_Serialize(oList)
        End Function
        Private Function p_Serialize(ByVal BaseType As Object) As String
            Dim ser As New DataContractJsonSerializer(BaseType.[GetType]())
            Dim m As New MemoryStream()
            m.Position = 0
            ser.WriteObject(m, BaseType)
            Return GetStringFromMemoryStream(m)
        End Function
        ''' <summary>
        ''' JSON Deserialize
        ''' </summary>
        ''' <param name="s"></param>
        ''' <param name="BaseType"></param>
        ''' <returns></returns>
        Public Function Deserialize(ByVal s As String) As Object
            Dim oList As New List(Of String)
            oList = p_Deserialize(s, oList.GetType)
            Return p_Deserialize(oList.Item(1), Type.GetType(oList.Item(0)))

        End Function

        Private Function p_Deserialize(ByVal s As String, ByVal BaseType As Object) As Object
            Dim ser As New DataContractJsonSerializer(BaseType)
            Dim m As MemoryStream = GetMemoryStreamFromString(s)
            m.Position = 0

            Return ser.ReadObject(m)
        End Function
    End Class

  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by Navedac on Sep 06, 2009 16:10
    Do not work with SL3 release.

    One Idéa ?

    Yvan
  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by Ross Brodskiy on Oct 15, 2009 02:44

    Yes it doesn't work with 3.0 :( so here is new utility class I just had to write...

    Imports System.IO
    Imports System.Text
    Imports System.Runtime.Serialization

    Public Class Conversion
        Public Function GetStringFromMemoryStream(ByVal m As MemoryStream) As String
            If (m Is Nothing) Or m.Length = 0 Then
                Return ""
            End If
            m.Flush()
            m.Position = 0
            Dim UTF8 = UTF8Encoding.UTF8
            Dim sr As New StreamReader(m, UTF8Encoding.UTF8)
            Dim s As String = sr.ReadToEnd()
            Return s
        End Function
        Public Function GetMemoryStreamFromString(ByVal s As String) As MemoryStream
            If (s Is Nothing) Or s.Length = 0 Then
                Return Nothing
            End If
            Dim a = System.Text.Encoding.UTF8.GetBytes(s)
            Dim m As New System.IO.MemoryStream(a, True)
            m.Position = 0
            Return m
        End Function
        Public Function Serialize(ByVal BaseType As Object) As String
            Dim ExactName = BaseType.GetType.AssemblyQualifiedName
            Dim Ser As String = p_Serialize(BaseType)
            Dim oList As New List(Of String)
            oList.Add(ExactName)
            oList.Add(Ser)
            Return p_Serialize(oList)
        End Function
        Private Function p_Serialize(ByVal BaseType As Object) As String
            If BaseType Is Nothing Then
                Throw New ArgumentNullException("your Object IsNothing to me!")
            End If
            Dim dcs As New DataContractSerializer(BaseType.[GetType]())
            Dim ms As New MemoryStream()
            dcs.WriteObject(ms, BaseType)
            Return Encoding.UTF8.GetString(ms.GetBuffer(), 0, CInt(ms.Position))
        End Function
        Public Function Deserialize(ByVal s As String) As Object
            Dim oList As New List(Of String)
            oList = p_Deserialize(s, oList)
            Dim Instance As Object = Activator.CreateInstance(Type.GetType(oList.Item(0)))
            Return p_Deserialize(oList.Item(1), Instance)
        End Function
        Public Function p_Deserialize(ByVal s As String, ByVal BaseType As Object) As Object
            Dim dcs As New DataContractSerializer(BaseType.GetType())
            Dim m As MemoryStream = GetMemoryStreamFromString(s)
            BaseType = dcs.ReadObject(m)
            Return BaseType
        End Function
    End Class

     

  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by Ross Brodskiy on Oct 15, 2009 02:46

    | the C# version...

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

    public class Conversion
    {
        public string GetStringFromMemoryStream(MemoryStream m)
        {
            if ((m == null) | m.Length == 0) {
                return "";
            }
            m.Flush();
            m.Position = 0;
            var UTF8 = UTF8Encoding.UTF8;
            StreamReader sr = new StreamReader(m, UTF8Encoding.UTF8);
            string s = sr.ReadToEnd();
            return s;
        }
        public MemoryStream GetMemoryStreamFromString(string s)
        {
            if ((s == null) | s.Length == 0) {
                return null;
            }
            var a = System.Text.Encoding.UTF8.GetBytes(s);
            System.IO.MemoryStream m = new System.IO.MemoryStream(a, true);
            m.Position = 0;
            return m;
        }
        public string Serialize(object BaseType)
        {
            var ExactName = BaseType.GetType.AssemblyQualifiedName;
            string Ser = p_Serialize(BaseType);
            List<string> oList = new List<string>();
            oList.Add(ExactName);
            oList.Add(Ser);
            return p_Serialize(oList);
        }
        private string p_Serialize(object BaseType)
        {
            if (BaseType == null) {
                throw new ArgumentNullException("your Object IsNothing to me!");
            }
            DataContractSerializer dcs = new DataContractSerializer(BaseType.GetType());
            MemoryStream ms = new MemoryStream();
            dcs.WriteObject(ms, BaseType);
            return Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Position);
        }
        public object Deserialize(string s)
        {
            List<string> oList = new List<string>();
            oList = p_Deserialize(s, oList);
            object Instance = Activator.CreateInstance(Type.GetType(oList.Item(0)));
            return p_Deserialize(oList.Item(1), Instance);
        }
        public object p_Deserialize(string s, object BaseType)
        {
            DataContractSerializer dcs = new DataContractSerializer(BaseType.GetType());
            MemoryStream m = GetMemoryStreamFromString(s);
            BaseType = dcs.ReadObject(m);
            return BaseType;
        }
    }

  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by Toby on Apr 10, 2010 00:46

    don't know if anyone tried the C# code but it doesn't compile and it generates XML not JSON.

    Also, it always serializes a list that includes the object type and instantiates that type when deserializing.

    Try this:

    public string GetStringFromMemoryStream(MemoryStream m)
    {
      if ((m == null) || m.Length == 0)
      {
        return "";
      }
      m.Flush();
      m.Position = 0;
      var UTF8 = UTF8Encoding.UTF8;
      StreamReader sr = new StreamReader(m, UTF8Encoding.UTF8);
      string s = sr.ReadToEnd();
      return s;
    }
    public MemoryStream GetMemoryStreamFromString(string s)
    {
      if ((s == null) || s.Length == 0)
      {
        return null;
      }
      var a = System.Text.Encoding.UTF8.GetBytes(s);
      System.IO.MemoryStream m = new System.IO.MemoryStream(a, true);
      m.Position = 0;
      return m;
    }
    public string Serialize(object BaseType)
    {
      var ExactName = BaseType.GetType().AssemblyQualifiedName;
      string Ser = p_Serialize(BaseType);
      List<string> oList = new List<string>();
      oList.Add(ExactName);
      oList.Add(Ser);
      return p_Serialize(oList);
    }
    private string p_Serialize(object BaseType)
    {
      if (BaseType == null)
      {
        throw new ArgumentNullException("No object to serialize");
      }
      DataContractJsonSerializer dcs = new DataContractJsonSerializer(BaseType.GetType());
      MemoryStream ms = new MemoryStream();
      dcs.WriteObject(ms, BaseType);
      return Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Position);
    }
    public object Deserialize(string s)
    {
      List<string> oList = new List<string>();
      oList = (List<string>)p_Deserialize(s, oList);
      object Instance = Activator.CreateInstance(Type.GetType(oList[0]));
      return p_Deserialize(oList[1], Instance);
    }
    public object p_Deserialize(string s, object BaseType)
    {
      DataContractJsonSerializer dcs = new DataContractJsonSerializer(BaseType.GetType());
      MemoryStream m = GetMemoryStreamFromString(s);
      BaseType = dcs.ReadObject(m);
      return BaseType;
    }

  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by Robert MacLean on Nov 11, 2010 11:28
    You do not need to close/dispose your stream in the serialise example, the reader will do that for you. In your case you risk disposing the stream twice.
  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by Mani on Nov 16, 2010 15:51

    This will work in SL3 also.

    You only need to reference System.ServiceModel.Web to use the DataContractJsonSerializer, not the System.Runtime.Serialization.Json.

  • -_-

    RE: JSON serialization and deserialization in Silverlight


    posted by Jim on Nov 23, 2010 17:02

    If you want code to serialize and deserialize Java objects, without any configuration, extra definition files, etc. check out http://code.google.com/p/json-io/.  We use this code on our servers to process JSON sent by our clients, and to send back JSON responses to our client applications.  We've found this to handle anything object graph we've thrown at it, and it is extremely quick.

Add Comment

Login to comment:
  *      *