I am trying to serialize some data using protobuf net. During the serialization I am getting an error that No serialization defined for the type Point3D. I found one issue somet
First off, protobuf-net is not a JSON serializer. It serializes from and to "Protocol Buffers" - the binary serialization format used by Google for much of their data communications.
That being said, there are several solutions to serialize a type, using protobuf-net, that cannot be decorated with ProtoContract
attributes:
For option 2, Since a Point3D is entirely defined by its X, Y and Z coordinates, it's very easy to introduce a serialization surrogate:
[ProtoContract]
struct Point3DSurrogate
{
public Point3DSurrogate(double x, double y, double z) : this()
{
this.X = x;
this.Y = y;
this.Z = z;
}
[ProtoMember(1)]
public double X { get; set; }
[ProtoMember(2)]
public double Y { get; set; }
[ProtoMember(3)]
public double Z { get; set; }
public static implicit operator Point3D(Point3DSurrogate surrogate)
{
return new Point3D(surrogate.X, surrogate.Y, surrogate.Z);
}
public static implicit operator Point3DSurrogate(Point3D point)
{
return new Point3DSurrogate(point.X, point.Y, point.Z);
}
}
And then register it with protobuf-net just once on startup like so:
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(Point3D), false).SetSurrogate(typeof(Point3DSurrogate));
Alternatively, for option 3, in startup you could define a contract for Point3D
like so:
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(Point3D), true);
ProtoBuf.Meta.RuntimeTypeModel.Default[typeof(Point3D)].Add(1, "X").Add(2, "Y").Add(3, "Z");
(In my opinion the surrogate is clearer despite requiring more code; defining the protocol entirely in runtime seems too fiddly.)
I don't recommend option 1 since you would need to add proxy properties to all classes that use Point3D
.