没有为类型定义的序列化程序:System.Windows.Media.Media3D.Point3D

时间:2015-11-03 09:47:13

标签: c# json serialization protobuf-net

我正在尝试使用protobuf net序列化一些数据。在序列化期间,我收到一个错误,没有为Point3D类型定义序列化。我发现了一个像这样的问题,但仍然无法实现和解决它。链接如下: - 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");
    }
}

我是JSON序列化/反序列化的初学者。如何解决这个问题?

如果无法使用Protobuf Net序列化Point3D,那么序列化/反序列化一个非常大的列表(有大约300000个项目)的其他选项有哪些?

1 个答案:

答案 0 :(得分:1)

首先,protobuf-net不是JSON序列化程序。它序列化了"Protocol Buffers" - 这是Google用于大部分数据通信的二进制序列化格式。

话虽如此,有几种使用protobuf-net序列化类型的解决方案,无法使用ProtoContract属性进行修饰:

  1. 如果包含其他类型,请使用代理或“shim”属性,如here所示,或
  2. 使用显示here或者
  3. 的代理
  4. 在运行时教授RuntimeTypeModel所有可序列化字段&amp; 无属性序列化部分中所述类型的属性here
  5. 对于选项2,由于Point3D完全由其X,Y和Z坐标定义,因此引入序列化代理非常容易:

    [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);
        }
    }
    

    然后在启动时使用protobuf-net注册一次,如下所示:

    ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(Point3D), false).SetSurrogate(typeof(Point3DSurrogate));
    

    或者,对于选项3,在启动时,您可以像Point3D那样定义合约:

    ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(Point3D), true);
    ProtoBuf.Meta.RuntimeTypeModel.Default[typeof(Point3D)].Add(1, "X").Add(2, "Y").Add(3, "Z");
    

    (在我看来,尽管需要更多代码,但代理更清晰;完全在运行时定义协议似乎过于繁琐。)

    我不建议使用选项1,因为您需要向使用Point3D的所有类添加代理属性。