Home > Silverlight > Silverlight binary serialization using Protobuf-net

Silverlight binary serialization using Protobuf-net

 

Introduction

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

 

Background

Silverlight don’t provide pure binary object serialization. Although the DataContractSerializer and the XmlSerializer are nice serialization infra, these classes are based just XML. The CustomBinarySerializer approach is good binary implementation way, but this way needs to make handy classes for each business objects.

 

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 support Silverlight version that enables us to save and load some data to the local disk or remote WCF server via HTTP.

Protobuf-csharp-port is another great C# version of the Protobuf. It follows most standard API’s and coding patterns of Java implementation. It uses tool generated codec for each business classes. 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 the performance of it 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.

Implementation Step1 : Setup project

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

projectlayout_thumb2

Implementation Step2 : Person business class

Let’s make the Person class with ‘ProtoContract’ and ‘ProtoMember’ attributes of ProtoBuf-net.

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;} 
    } 
}

Implementation Step3 : Design a display xaml page

This is design preview in Visual Studio after design a main display xaml page.

xamlpreview

Let’s check the xaml code.

<UserControl x:Class="SLBufferSerializer.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
  <Grid x:Name="LayoutRoot">
        <StackPanel Width="200" Margin="20">
            <TextBlock x:Name="txtStatus" Text="Ready"></TextBlock>
            <Button x:Name="btnTest" Content="Click" Click="btnTest_Click"></Button>
            <Grid Background="White">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="35*" />
                    <ColumnDefinition Width="65*" />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                
                <TextBlock Grid.Column="0" Grid.Row="0" Text="Id"></TextBlock>
                <TextBlock Grid.Column="1" Grid.Row="0" x:Name="txt1"></TextBlock>
                <TextBlock Grid.Column="0" Grid.Row="1" Text="Name"></TextBlock>
                <TextBlock Grid.Column="1" Grid.Row="1" x:Name="txt2"></TextBlock>
                <TextBlock Grid.Column="0" Grid.Row="2" Text="Address1"></TextBlock>
                <TextBlock Grid.Column="1" Grid.Row="2" x:Name="txt3"></TextBlock>
                <TextBlock Grid.Column="0" Grid.Row="3" Text="Address2"></TextBlock>
                <TextBlock Grid.Column="1" Grid.Row="4" x:Name="txt4"></TextBlock>
                
            </Grid>
        </StackPanel>
  </Grid>
</UserControl>

Implementation Step4 : IsolatedStorage helper methods

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

        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);
                }
            }
        }

Implementation Step5 : Implementing code-behind logics

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

...
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.

SilverlightProtobufNet

You can download the source project file at here.

Before running this project, you should set the static start page of the test web site.

References

For more information, follow this link.

Advertisements
  1. June 23, 2013 at 2:17 am

    If you are going for most excellent contents like me, only visit this web page
    everyday as it offers quality contents, thanks

  2. August 9, 2013 at 7:42 am

    Hi there, You have done a great job. I’ll certainly digg it and personally recommend to my friends. I am confident they’ll
    be benefited from this website.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: