Click here to Skip to main content
15,867,488 members
Articles / Programming Languages / C#

Silverlight Binary Serialization using Protobuf-net

Rate me:
Please Sign up or sign in to vote.
5.00/5 (8 votes)
29 Apr 2010CPOL3 min read 69.1K   620   26   18
How to serialize a pure .NET object class to a fast binary data

Introduction

This article shows you how to serialize a pure .NET object class to a fast binary data in Silverlight.

Background

Silverlight does not provide pure binary object serialization. Although the DataContractSerializer and the XmlSerializer are nice serialization infra, these classes are based on XML. The CustomBinarySerializer approach is a good binary implementation method, but it needs to make handy classes for each business object.

Protobuf-net

The Protobuf-net is one of the Google Protobuf C# implementation components, which provides more compact and fast binary serialization of pure .NET object classes. Also the component supports the Silverlight version that enables us to save and load some data to the local disk, remote WCF server via HTTP or low level TCP/IP socket using the SocketAsyncEventArgs class. It generates the raw level byte[] for the primitive types, but the Silverlight serializers are based on XML data.

Protobuf-csharp-port is another great C# version of the Protobuf. It follows most standard APIs and coding patterns of Java implementation. It uses tool generated codec for each business class. But I selected Protobuf-net as the base binary codec engine of the Protobuf as it follows the basic .NET architecture.

It uses attribute reflection but its performance is fast enough. Also the engine enables us to use clean pure business object classes and basic stream classes more easily. It is easy to use the Protobuf-net assembly in Silverlight, while using the Protobuf-csharp-port in the Silverlight needs several code-fix tasks.

Silverlight IsolatedStorage

In Silverlight, we can store some data to our local hard disk using IsolatedStorage. The storage space and location are limited, but the limit can be unlocked of Silverlight Out-Of-Browser environment.

We will use IsolatedStorage for saving and loading our data with Protobuf-Net binary serialization.

Using the Code

Setup Project

We will use VS2008 SP1 and Silverlight 3. We should add Silverlight application project template with web site test option. The following image is the final layout of our project.

You can use the protobuf-net assembly in any "Silverlight Class Library or Application" project type. This SLBufferSerializer is a Silverlight Application project with an auto generated Silverlight ASP.NET web site by VS2008.

Make sure to set the start page in the web site to use F5. See this image how to set the web site project properties.

Person Business Class (Person.cs)

Let’s make the Person pure class with ‘ProtoContract’ and ‘ProtoMember’ attributes of ProtoBuf-net. This approach is very similar to the XMLSerializer method. The numbers of below attributes are the required order by the Google's protobuf.

C#
using System;
using ProtoBuf; 
namespace SLBufferSerializer
{
    [ProtoContract]
    public class Person {
        [ProtoMember(1)]
        public int Id {get;set;}
        [ProtoMember(2)]
        public string Name { get; set; }
        [ProtoMember(3)]
        public Address Address {get;set;}
    }
    [ProtoContract]
    public class Address {
        [ProtoMember(1)]
        public string Line1 {get;set;}
        [ProtoMember(2)]
        public string Line2 {get;set;}
    }
}

Design a Display XAML Page (MainPage.xaml)

This is design preview in Visual Studio after designing a main display XAML page. You can see the detailed XAML code in the source of this article.

IsolatedStorage Helper Methods (MainPage.xaml.cs)

These are helper methods for Protobuf-net serialization to the IsolatedStorage. The codec engine uses Stream implementation basically, so IsolatedStorageStream class is also available.

You can also place these methods to another static helper class:

C#
private static void SaveToStorage<T>(string filePath, T instance)
{
    using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (IsolatedStorageFileStream stream = 
	new IsolatedStorageFileStream(filePath, FileMode.CreateNew, storage))
        {
            Serializer.Serialize<T>(stream, instance);
        }
    }
}
private static T LoadFromStorage<T>(string filePath)
{
    using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (IsolatedStorageFileStream stream = 
	new IsolatedStorageFileStream(filePath, FileMode.Open, storage))
        {
            return Serializer.Deserialize<T>(stream);
        }
    }
}

Implementing Code-behind Logic (MainPage.xaml.cs)

Initialize a person instance. Let us save and load the serialized data of the person instance.

C#
...
using ProtoBuf;
namespace SLBufferSerializer
{
    public partial class MainPage : UserControl
    {
        private readonly string fileName = "test.txt";
        public MainPage()
        {
            InitializeComponent();
            this.ProtobufSerialize();
        }
        private void ProtobufSerialize()
        {
            var person = new Person
            {
                Id = 12345,
                Name = "Fred",
                Address = new Address
                {
                    Line1 = "Flat 1",
                    Line2 = "The Meadows"
                }
            };
            try
            {
                SaveToStorage<Person>(fileName, person);
            }
            catch (IsolatedStorageException)
            {
            }
        }
        private void btnTest_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                Person person = LoadFromStorage<Person>(fileName);
                this.txtStatus.Text = "De-Serialized....";
                this.txt1.Text = person.Id.ToString();
                this.txt2.Text = person.Name;
                this.txt3.Text = person.Address.Line1;
                this.txt4.Text = person.Address.Line2;
            }
            catch (IsolatedStorageException)
            {
            }
        }
 ...
    }
}

The Final Silverlight Result Screen

Here is the executed screen after de-serialization.

References

For more information, follow the links given below:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWhat about WPF applications ? Pin
Yogesh Potdar25-May-11 20:00
Yogesh Potdar25-May-11 20:00 
AnswerRe: What about WPF applications ? Pin
Pawel idzikowski6-Aug-11 20:19
Pawel idzikowski6-Aug-11 20:19 
GeneralSilverlight 3 already has binary serialization so why this Pin
AndrusM26-Apr-10 23:29
AndrusM26-Apr-10 23:29 
GeneralRe: Silverlight 3 already has binary serialization so why this [modified] Pin
Sangsu Park 9927-Apr-10 3:04
Sangsu Park 9927-Apr-10 3:04 
Thank you. Andrus.
Most of cases, it is good to use the original DataContractSerializer and XmlSerializer codec.
But This protobuf-codec provides several powerful advantages in some limited distributed enterprise systems.

1. absolutely fast small byte array.
it create raw byte[] with high speed for the raw primitive types. Above silverlight codecs are based on large XML data.

2. interoperability
The data using protobuf can be transferred via raw level TCP/IP socket.
In silverlight, you can send raw byte[] via the SocketAsyncEventArgs context.
So, you can communicate directly with other enterprise systems like J2EE,PHP or any other legacy servers.
There are lots of systems providing the ProtoBuff like the Jboss netty or the Apache Mina.

Thank you for your comment. Smile | :)

modified on Tuesday, April 27, 2010 9:13 AM

GeneralRe: Silverlight 3 already has binary serialization so why this Pin
AndrusM27-Apr-10 4:52
AndrusM27-Apr-10 4:52 
GeneralRe: Silverlight 3 already has binary serialization so why this Pin
Marc Gravell27-Apr-10 12:23
Marc Gravell27-Apr-10 12:23 
GeneralRe: Silverlight 3 already has binary serialization so why this Pin
AndrusM27-Apr-10 23:29
AndrusM27-Apr-10 23:29 
GeneralRe: Silverlight 3 already has binary serialization so why this Pin
Marc Gravell28-Apr-10 1:39
Marc Gravell28-Apr-10 1:39 
GeneralRe: Silverlight 3 already has binary serialization so why this Pin
AndrusM3-May-10 0:31
AndrusM3-May-10 0:31 
GeneralRe: Silverlight 3 already has binary serialization so why this Pin
Marc Gravell3-May-10 9:54
Marc Gravell3-May-10 9:54 
GeneralRe: Silverlight 3 already has binary serialization so why this Pin
AndrusM14-May-10 3:17
AndrusM14-May-10 3:17 
GeneralRe: Silverlight 3 already has binary serialization so why this Pin
Marc Gravell27-Apr-10 12:29
Marc Gravell27-Apr-10 12:29 
GeneralGood Work Pin
Member 386383122-Apr-10 4:55
Member 386383122-Apr-10 4:55 
GeneralRe: Good Work Pin
Sangsu Park 9922-Apr-10 16:39
Sangsu Park 9922-Apr-10 16:39 
GeneralNote that you can also use the standard "WCF" attributes Pin
Marc Gravell18-Apr-10 22:07
Marc Gravell18-Apr-10 22:07 
GeneralRe: Note that you can also use the standard "WCF" attributes Pin
Sangsu Park 9918-Apr-10 22:53
Sangsu Park 9918-Apr-10 22:53 
GeneralComments Pin
Md. Marufuzzaman18-Apr-10 21:09
professionalMd. Marufuzzaman18-Apr-10 21:09 
GeneralRe: Comments Pin
Sangsu Park 9918-Apr-10 22:40
Sangsu Park 9918-Apr-10 22:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.