2012-02-18 69 views
1

我正在使用proto-buf的V2。當我使用2個類序列化一個示例項目時,當我在字段中不包含[ProtoMember(x)]時,proto-buf序列化。我只是在課前放了[ProtoContract]。我不知道爲什麼會發生這種情況?序列化爲空

當我在所有類之前放置[ProtoContract]並且沒有爲任何類中的任何字段添加[ProtoMember(x)]之後嘗試序列化我的實際項目時,我沒有收到錯誤,但是序列化文件爲空(0字節)。有誰知道發生了什麼?我們是否需要在每個領域之前放置原型以便序列化?如果是這樣,爲什麼我的示例項目沒有在項目中使用任何protomember而被序列化?

我的真實項目大約有20-30個類,每個類都有很多字段?我是否需要在所有課程的所有領域放置原型?

感謝您的洞察力。

回答

1

序列化一個沒有感興趣的字段寫的對象不是錯誤這樣 - 非常不尋常,但不嚴格錯誤 - 確實:它不會抱怨。零字節是protobuf的有效序列化長度,即使字段要序列化(如果它們全部變爲null/default-value/conditional-and-disabled/etc)。實際上,本週早些時候出現了,因爲新的MS WebAPI假定(在這種情況下錯誤地)零字節的有效載荷長度是不可能的,因此不會調用解串器。嘆。

但要回答你的問題!

如果你是絕對肯定你不會改變你的DTOs,你可以問protobuf-net來彌補數字;這是「ImplicitFields」,並且可以做到無論是作爲:

  • 所有公共成員(字段或屬性) - 這是非常像的XmlSerializer是如何工作的
  • 所有領域(私有或公共) - 這與BinaryFormatter的工作方式非常相似

ImplicitFields的一個問題是:它生成的數字基本上就是合約。 ImplicitFields通過按字母順序排序並使用連續的數字生成數字。如果您更改DTO(添加/刪除/重命名成員),它可能會開始考慮不同的數字,這是一個重大變化:數據庫/磁盤上的任何舊數據可能無法正確反序列化。

如果你確信你的合同是固定的,你可以通過(道歉,如果我把它一點點的錯誤 - 不是在PC)啓用此:

[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)] 
public class Foo { /* blah blah blah */ } 

當然,你可以隨時更改此到後面的顯式[ProtoMember(n)] - 按照按字母順序排列的成員佈局,只需使用1,2,3等,然後對您的DTO進行任何更改。