1

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 something like this but still unable to implement and resolve it. Link is as follow :- No serializer defined for type: System.Drawing.Color

[ProtoContract]
public class ReturnPanelData
{
    [ProtoMember(1)]
    public Point3D PlacedPoint3D { get; set; }
    [ProtoMember(2)]
    public double PlacementAngle { get; set; }
    [ProtoMember(3)]
    public string PanelName { get; set; }
}
[ProtoContract]
public class ReturnDataType
{
    [ProtoMember(1)]
    public List<ReturnPanelData> ReturnList { get; set; }
    [ProtoMember(2)]
    public double RemainderArea { get; set; }
    [ProtoMember(3)]
    public int Height { get; set; }
    [ProtoMember(4)]
    public int Width { get; set; }
    [ProtoMember(5)]
    public Point3D BasePoint3D { get; set; }
}
class Program
{
    private static HashSet<ReturnDataType> _processedList = new HashSet<ReturnDataType>();
    static void Main(string[] args)
    {
        using (var file = File.Create(@"D:\SavedPCInfo2.bin"))
        {
            Serializer.Serialize(file, _processedList);
        }
        Console.WriteLine("Done");
    }
}

I am a begineer in JSON serialization/deserialization. How to resolve this issue ?

If it is not possible to serialize Point3D with Protobuf Net, what are the other options to serialize/deserialize a very big list (having approx 300000 items) ?

Community
  • 1
  • 1
Vishal Goyal
  • 193
  • 14
  • Why not Newtonsoft.Json? – Camo Nov 03 '15 at 09:51
  • @Rinecamo : Before choosing serialization technique I searched some articles and found that to serialize/deserialize big list it is a better option to use Protobuf Net. http://stackoverflow.com/questions/26368550/efficient-way-of-storing-and-retrieving-large-json-100-mb-from-a-file-using – Vishal Goyal Nov 03 '15 at 09:56

1 Answers1

1

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:

  1. When contained by some other type, use a proxy or "shim" property as is shown here, OR
  2. Use a surrogate as is shown here, OR
  3. In runtime teach the RuntimeTypeModel about all serializable fields & properties of the type as described here in the section Serializing without 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.

dbc
  • 104,963
  • 20
  • 228
  • 340