2013-01-10 42 views
1

我有兩個簡單的類,我想用protobuf-net序列化。一切看起來不錯,但是當我反序列化Body屬性爲null時。任何想法我做錯了什麼?Newbe試圖用protobuf-net序列化對象

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

回答

1

兩個問題:

  1. protobuf網需要一個正整數,每個成員關鍵;這可以通過Order=[DataMember]上提供。低的數字更好,所以通常這意味着123 ...

  2. 的protobuf的規範是綁定到架構的串;它希望提前瞭解數據; object不能很好地工作。

但是這會工作:

[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網特有的(它不會起到很好地重新可移植性)。我鼓勵你看看打字的方法第一個。但可以做到這一點:我只是喜歡它,如果你沒有,P

如果不能改變現有的模式,那麼第一件事我會建議是:添加一個單獨的DTO模型看起來很像您現有的模型,但標記爲序列化,並且與之一起工作 - 並在兩個模型之間進行填充。如果不是一個選項,則需要將系統配置爲a:define成員密鑰,並且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.*

+0

任何想法如何使當前的示例與對象一起工作? – mynkow

+0

@mynkow是;編輯於 –

+0

10x Marc。當body是object類型時,RuntimeTypeModel有效。困擾我的是Inner可以是任何類型。例如Outer是EventMessage的包裝,每個EventMessage都有不同的字段或屬性。你是否建議使用反射來將這些事件消息添加到condif中? – mynkow

0

爲對象的屬性,您可以使用此:

[ProtoMember(1,DynamicType = true)] public object Value {get;組; }

+0

Proto屬性是不同的故事 – mynkow