Reputation: 379
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
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
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