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