1

需要序列化一些包含 DrawingBrush 的 BL 结构。我已将其重写如下:

[ProtoContract]
public class BaseProtoBuf : INotifyPropertyChanged, IFormattable
{
    [ProtoMember(1)]
    public string ID { get; set; }
    // Bunch of properties of .net primitive types
    // ..
    private DrawingBrush _geometry;
    [ProtoMember(9)]
    [Browsable(false)]
    public DrawingBrush Geometry
    {
            get { return _geometry; }
            set
            {
                _geometry = value; 
                ScaleDrawing();
            }
    }
}
[ProtoContract]
[ProtoInclude(1, typeof(string))]
// All other includes
[ProtoInclude(9, typeof(DrawingBrush)]
public class DerivedProtoBuf : BaseProtoBuf, ICloneable
{        
    // Some additional properties of primitive types, annotated starting with ProtoMember 10 and so on
}

要序列化我正在执行以下代码:

const string fileName = "Protobuf.bin";
using (var file = File.Create(fileName))
{
    file.Position = 0;
    var testBase = new BaseProtoBuf
                                   {
                                      Height = 100,
                                      Width = 100,
                                      Name = "Test 1",
                                      OffsetX = 200,
                                      OffsetY = 200,
                                      Geometry = sourceList[0].Geometry // some not-null DrawingBrush
                                  };
    Serializer.Serialize(file, testBase);
    file.Position = 0;
    var restored = Serializer.Deserialize<BaseProtoBuf>>(file);
}
}

我需要序列化 ​​Derived 类对象,但在 Base 序列化期间,我得到“没有找到合适的默认 DrawingBrush 编码”。认为这是因为 DrawingBrush 对于某些对象可以为空,但在测试中它不是。正确序列化的任何解决方法 1) 具有非空 DrawingBrush 的基础对象 2) 具有空 DrawingBrush 的派生对象?提前致谢。

4

2 回答 2

3

为简单的 WPF Brush 序列化正确的 RuntimeTypeModel 配置:

RuntimeTypeModel.Default.Add(typeof(Brush), false)
               .AddSubType(300, typeof(SolidColorBrush));
RuntimeTypeModel.Default.Add(typeof(SolidColorBrush), false)
                .Add("Color");
RuntimeTypeModel.Default.Add(typeof(Color), false)
                .Add("A", "R", "G", "B"); // needed for proper color serialization
RuntimeTypeModel.Default.Add(typeof(SolidColorBrush), false)
        .Add("Color");
RuntimeTypeModel.Default.Add(typeof(DrawingBrush), false)
        .Add("Stretch", "Drawing");
RuntimeTypeModel.Default.Add(typeof(Drawing), false)
        .AddSubType(100, typeof(DrawingGroup))
        .AddSubType(200, typeof(GeometryDrawing));
RuntimeTypeModel.Default.Add(typeof(DrawingGroup), false)
        .Add("Children");
RuntimeTypeModel.Default.Add(typeof(Pen), false)
        .Add("Brush", "Thickness", "LineJoin");
RuntimeTypeModel.Default.Add(typeof(GeometryDrawing), false)
       .Add("Brush", "Geometry", "Pen");
于 2012-05-04T12:07:38.233 回答
2

由于未定义合同,因此 DrawingBrush 不能立即序列化。这里有各种选项:

  • 如果类型相当简单,您可以在运行时通过 RuntimeTypeModel 配置合约,根据需要添加属性/子类型等
  • 在某些情况下,可能首选使用“代理”——一种具有双向转换运算符的类型,用作动态 DTO——同样,可以通过 RuntimeTypeModel 指定代理;“代理”让您使用现有模型,但根据需要交换 DTO 类型
  • 否则,请考虑在模型中避免使用特定于框架的类型,而只使用带有所需信息的 DTO 类型。在运行时从中构造框架所需的值
于 2012-04-28T08:05:01.703 回答