34

I'm trying to get started with protobuf.net.

I've downloaded the latest version from here, implemented a [ProtoContract] class, and now I'm trying to serialize it with ProtoBuf.Serializer.Serialize as described in the documentation. The problem is, that there is no such method.

How do I write [ProtoContract] to disk?

UPDATE Apparently, I've got the wrong version of it or something, but here's what my Serialize class looks like:

protobuf.net Serializer class as I see it

Parimal Raj
  • 20,189
  • 9
  • 73
  • 110
Arsen Zahray
  • 24,367
  • 48
  • 131
  • 224

2 Answers2

32

This must help you get started with it : Source & Credit & Marc Gravell


The simplest way to get started is simply to write your data:

class Person {
    public int Id {get;set;}
    public string Name {get;set;}
    public Address Address {get;set;}
}
class Address {
    public string Line1 {get;set;}
    public string Line2 {get;set;}
}

That is a good start, but by itself is not enough for protobuf-net. Unlike XmlSerializer, the member-names are not encoded in the data - instead, you must pick an integer to identify each member. Additionally, to show intent it is necessary to show that we intend this type to be serialized (i.e. that it is a data contract):

[ProtoContract]
class Person {
    [ProtoMember(1)]
    public int Id {get;set;}
    [ProtoMember(2)]
    public string Name {get;set;}
    [ProtoMember(3)]
    public Address Address {get;set;}
}
[ProtoContract]
class Address {
    [ProtoMember(1)]
    public string Line1 {get;set;}
    [ProtoMember(2)]
    public string Line2 {get;set;}
}

Since "protocol buffers" is a binary format, protobuf-net is based heavily around the Stream class; this makes it simple to use with a wide variety of implementations. 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.


Update : Download this package All seems fine

Community
  • 1
  • 1
Parimal Raj
  • 20,189
  • 9
  • 73
  • 110
10

It sounds like you have picked up a "CoreOnly" build, maybe for iOS or Unity? That means you are using the google-code download. In the root of that package is a "What files do I need.txt" which explains what the different builds are for. You should probably be using a "Full" build. Or more simply, use the NuGet deploy which only includes "Full" builds.

If you want to use "CoreOnly", you should probably be using the separate "precompile" tool to generate a custom serializer, then:

 var ser = new MyCustomSerializer();
 ser.Serialize(...);

This scenario is intended primarily for light frameworks like Windows Phone, Silverlight, iOS etc - where meta-programming / reflection is either very limited or completely disallowed.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900