Newbe试图用protobuf-net序列化对象

时间:2013-01-10 13:21:26

标签: protobuf-net

我有两个简单的类,我想用protobuf-net序列化。一切看起来都不错,但是当我反序列化时,Body属性为null。知道我做错了吗?

using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using ProtoBuf;

namespace Protobuf_test
{
    public class Program
    {
        private static void Main(string[] args)
        {
            var innerObject = new Inner() { Id = Guid.NewGuid() };
            var outerObject = new Outer() { Body = innerObject };

            using (var stream = File.Create("serialized.bin"))
            {
                Serializer.Serialize(stream, outerObject);
            }
            using (var file = File.OpenRead("serialized.bin"))
            {
                var deserialized = Serializer.Deserialize<Outer>(file);
            }
        }
    }

    [DataContract]
    public class Inner
    {
        [DataMember]
        public Guid Id { get; set; }
    }

    [DataContract]
    public class Outer
    {
        [DataMember]
        public object Body { get; set; }
    }
}

2 个答案:

答案 0 :(得分:1)

两个问题:

  1. protobuf-net每个成员需要一个正整数 key ;这可以通过Order=上的[DataMember]提供。数字越低越好,通常这意味着123 ......

  2. protobuf规范是一个模式绑定的序列化器;它希望提前了解数据; object不能很好地运作。

  3. 但这可行:

    [DataContract]
    public class Inner
    {
        [DataMember(Order=1)]
        public Guid Id { get; set; }
    }
    
    [DataContract]
    public class Outer
    {
        [DataMember(Order=1)]
        public Inner Body { get; set; }
    }
    

    支持灵活键入的数据(即object),但请注意它是protobuf-net特定的(它不能很好地实现可移植性)。我鼓励你先看一下的键入方法。但它可以这样做:如果你不这样做,我会更喜欢它; p

    如果您无法更改现有模型,那么我建议的第一个事情是:添加一个看起来很像现有模型的单独DTO模型,但是标记为序列化,并使用它 - 并在两个模型之间填充。如果 不是一个选项,则需要将系统配置为:为成员定义键,然后b:告诉它使用动态。例如:

    var config = RuntimeTypeModel.Default;
    config.Add(typeof(Inner),false).Add("Id");
    config.Add(typeof(Outer), false).AddField(1, "Body").DynamicType = true;
    

    (注意:Serializer.*基本上是RuntimeTypeModel.Default.*的捷径,所以这个配置与Serializer.*上的方法有关。

答案 1 :(得分:0)

对于object属性,您可以使用:

[ProtoMember(1,DynamicType = true)] 公共对象价值{get;组; }