Serialization And Deserialization In C# Using Protobuf-net.dll

Introduction

Protobuf-net is a faster .NET library for serialization and deserialization based on Google's Protocol Buffers. It is designed to be a language-neutral, platform-neutral, extensible way of serializing structured data for use in communications protocols and efficient data storage (far smaller than xml). You can define how you want your data to be structured once; then, you can use specially generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages. It allows you to serialize your .NET objects efficiently and easily. It is compatible with .NET 2.0/3.0/3.5/4.0, .NET CF 2.0/3.5, Mono 2.x, Silverlight, etc.

It contains a few attributes which have significance in serializing an object:

  • [ProtoContract]: ProtoContract is a sealed class that inherits from the Attribute class. It needs to be defined above a class and indicates that this class will serialize.
  • [ProtoMember(N)]: ProtoMember is a sealed class that inherits from the Attribute class. It needs to be defined above a property/field and indicate that this field will serialize. Here, N represents the number in which order it will serialize. It will start numbering at 1 even if your class uses ProtoMember(N) explicitly in some fields because it serializes in alphabetical order.
  • [ProtoIgnore]: ProtoContract is a sealed class that inherits from the Attribute class. It needs to be defined above a property/field and indicates that this field will ignore (won’t serialize) when serialization occurs.

Protobuf-net is not compatible with the standard .NET serialization system, which means,

  • It ignores the [Serializable] attribute.
  • It does not support custom serialization using ISerializable.

We will discuss the following points,

  1. Installation of protobuf-net.
  2. Serializing an object.
  3. Deserialize byte array to an object.
  4. Advantages of protobuf-net.

Installation

To install protobuf-net, you need to use NuGet Package Manager, which provides the latest version of the dll. Follow Figure 1, which shows how to install the dll.

Figure 1. Install through Nuget Package Manager

or

TOOLS -> Library Package Manager -> Package Manager Console.

Install-Package protobuf-net

Note. If you are using VS 2012/2013 or lower, then you need to provide a version in command.

Install-Package protobuf-net -Version 2.0.0.668.

Before starting the demonstration, we need to decorate the entity. Let's say Project is the entity that has two fields, ID and Name. The ProtoContract attribute defines to make a class serializable, and Protomember defines to make members/properties serializable.

[ProtoContract(SkipConstructor = true)]
public class Project
{
    [ProtoMember(1)]
    public int ID { get; set; }

    [ProtoMember(2)]
    public string Name { get; set; }
}

Serialization

Serialization is the process of converting an object into a stream of bytes to store the object or transmit it to memory, database, or file. Its aim is to save the state of an object in order to be able to recreate it in the future when needed. The below code snippet defines a method (ProtoSerialize()) that receives an object. Then, it is called Serialize(), which converts the object to a stream of bytes through the MemoryStream object.

public static byte[] ProtoSerialize<T>(T record) where T : class
{
    if (record == null) return null;

    try
    {
        using (var stream = new MemoryStream())
        {
            Serializer.Serialize(stream, record);
            return stream.ToArray();
        }
    }
    catch
    {
        // Log error
        throw;
    }
}

The following figure shows the result after Serialization. It converts the Project object to a bytes array through the ProtoSerialize() method.

Figure 2. Result after Serialization

Deserialization

Deserialization is the process of converting streams of bytes into an object. It is the reverse process of Serialization (discussed above). The code snippet below defines the Deserialize method(ProtoDeserialize()) with a byte array as a parameter. Then, it converts the byte array to a MemoryStream object. Next, it is called Deserialize(), which passes the MemoryStream object as a parameter and returns an actual object.

public static T ProtoDeserialize<T>(byte[] data) where T : class
{
    if (data == null) return null;

    try
    {
        using (var stream = new MemoryStream(data))
        {
            return Serializer.Deserialize<T>(stream);
        }
    }
    catch
    {
        // Log error
        throw;
    }
}

The following figure shows the result after Deserialization. It converts the bytes array to a Project object through the ProtoDeserialize() method.

Figure 3. Result after Deserialization

Advantages

  • Very fast processing.
  • It is hard to decode without knowing the schema.
  • Very useful for internal APIs.
  • Easy Language Interoperability.
  • Generic request/response allows more flexibility.

Performance comparison

Figure 4. Serialization Performance graph of libraries

Conclusion

In this article, we discussed serialization and deserialization using protobuf-net dll. We can perform the same functionality in different ways, such as DataContractSerializer, JSON.NET, JavaScriptSerializer, etc. However, protobuf-net provides better performance than other methods. So use protobuf-net dll whenever you develop internal APIs and perform serialization/deserialization.


Similar Articles