ak1
ak1

Reputation: 379

How to Serialize/De-Serialize List<MyClass> using protobuf-net C#

I have a simple class like

public class Customer{
 public long Id;
 public string Name;
 ....
}

I have a List and I want to serialize it using protobuf-net. Please guide me simple and efficient way of serializing and de-serializing this.

EDIT-1 I was looking at the unit test available with the protobuf-net source code, it uses 2 ways to serialize, using reflection and with Model (which internally handles the mapping based on ToString).

What I followed from the source code is that I used the same technique as tested in the project folder e-ProtoBufNetWithModel of the source code and created a TypeModel...

public static TypeModel CreateModel()
    {
        RuntimeTypeModel model = TypeModel.Create();

        model.Add(typeof(Customer), false)
        .Add(1, "Id")
        .Add(1, "Name");

        TypeModel compiled = model.Compile();

        return compiled;
    }

Problem Area

 public static Stream SerializeUsingProtobuf(IList<Customer> pSource)
    {
        var model = CreateModel();
        using (Stream memoryStream = new MemoryStream())
        {
            model.Serialize(memoryStream, pSource);
            return memoryStream;
        }

    }

On TypeModel compiled = model.Compile();, it raises exception Duplicate field-number detected; 1

Upvotes: 1

Views: 4154

Answers (2)

Marc Gravell
Marc Gravell

Reputation: 1062780

Each field to serialize requires a different tag (a positive integer). Instead of 1 and 1, try using 1 and 2 when calling Add. Or simpler, just Add("Id", "Name");

Upvotes: 1

NoWar
NoWar

Reputation: 37633

https://code.google.com/p/protobuf-net/

The short version (see also the old home page)

Serialization is a pain. protobuf-net is designed to be easily used on your existing code with minimal changes (of from an optional .proto schema), enabling fast and portable binary serialization on a wide range of .NET platforms.

Rather than being "a protocol buffers implementation that happens to be on .NET", it is a ".NET serializer that happens to use protocol buffers" - the emphasis is on being familiar to .NET users (for example, working on mutable, code-first classes if you want). I've also added a range of commonly requested features beyond the regular protobuf design, to help meet the every-day demands of .NET programmers (inheritance, reference-tracking, etc).

Usage is very simple; at the most basic level, simply read from a stream or write to a stream; see Getting Started:

// write to a file
Serializer.Serialize(outputStream, person);

...

// read from a file
var person = Serializer.Deserialize<Person>(inputStream);

Oh, and it is very fast; both in CPU and in bandwidth.

There is some VS tooling if you want to work from .proto files in visual studio, but you don't need that - you can just write a class, tell the serializer how to work with it (most commonly by adding a few attributes, but that is up to you), and serialize away.

https://code.google.com/p/protobuf-net/wiki/GettingStarted

Serializing Data Since "protocol buffers" is a binary format, protobuf-net is based heavily around the Stream class; this makes it possible to use with a wide variety of implementations simply. For example, to write to a file:

var person = new Person { Id = 12345, Name = "Fred", Address = new Address { Line1 = "Flat 1", Line2 = "The Meadows" } }; using (var file = File.Create("person.bin")) { Serializer.Serialize(file, person); }

This writes a 32 byte file to "person.bin". It might not be obvious in the above, but Serialize is a generic method - the line could also be:

  using (var file = File.Create("person.bin")) {
        Serializer.Serialize<Person>(file, person);
    }

But most of the time we can let the compiler's generic type inference do the work for us.

Deserializing Data We also need to get out data back!

 Person newPerson;
    using (var file = File.OpenRead("person.bin")) {
        newPerson = Serializer.Deserialize<Person>(file);
    }

This reads the data back from "person.bin". Note we need to tell it the type this time (the ), but otherwise the code is very similar.

Upvotes: 1

Related Questions