翔如菲菲

其实天很蓝,阴云总会散;其实海不宽,此岸连彼岸.

导航

Silverlight Binary Serialization using Protobuf-net

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.
using System;
using ProtoBuf; 
namespace SLBufferSerializer
{
    [ProtoContract]
    
public class Person {
        [ProtoMember(
1)]
        
public int Id {get;set;}
        [ProtoMember(
2)]
        
public string Name { getset; }
        [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:

 

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:

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.

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

 

Source Article URL:
http://www.codeproject.com/KB/silverlight/silverlight-protobufnet.aspx

posted on 2011-06-18 09:23  翔如飞飞  阅读(524)  评论(0编辑  收藏  举报