【问题标题】:Serialization is empty序列化为空
【发布时间】:2012-02-18 05:29:11
【问题描述】:

我正在使用 proto-buf 的 V2。当我用 2 个类序列化一个示例项目时,当我在字段中不包含 [ProtoMember(x)] 时,proto-buf 会序列化。我只是将 [ProtoContract] 放在课程之前。我不知道为什么会这样?

当我在将 [ProtoContract] 放在所有类之前并且没有为任何类中的任何字段添加 [ProtoMember(x)] 之后尝试序列化我的真实项目时,我没有收到错误但序列化文件为空( 0 个字节)。有谁知道发生了什么?我们是否需要将 protomember 放在每个字段之前才能进行序列化?如果是这样,为什么我的示例项目没有在项目中使用任何 protomember 就被序列化了?

我的实际项目大约有 20-30 个类,每个类都有很多字段?我是否需要将 protomember 放在所有类的所有字段中?

感谢您的洞察力。

【问题讨论】:

    标签: protobuf-net


    【解决方案1】:

    序列化一个没有有趣字段可写的对象并不是一个错误 - 非常不寻常,但严格来说不是一个错误 - 确实如此:它不会抱怨。零字节是 protobuf 的有效序列化长度,即使 with 字段要序列化(如果它们都变成 null/default-value/conditional-and-disabled/etc)。实际上,这是本周早些时候出现的,因为新的 MS WebAPI 假设(在这种情况下不正确)零字节的有效负载长度是不可能的,因此 不调用反序列化器。叹息。

    但是要回答你的问题!

    如果你绝对确定你不会改变你的 DTO,你可以要求 protobuf-net 来弥补数字;这是“ImplicitFields”,可以这样做:

    • 所有 public 成员(字段或属性) - 这与 XmlSerializer 的工作方式非常相似
    • 所有字段(私有或公共) - 这与 BinaryFormatter 的工作方式非常相似

    ImplicitFields 的一个问题是:它生成的数字本质上是合同。 ImplicitFields 通过按字母顺序并仅使用连续编号来生成数字。如果您更改 DTO(添加/删除/重命名成员),它可能会开始考虑不同的数字,这是一个重大变化:磁盘/数据库/等中的任何旧数据都可能无法正确反序列化。

    如果您确定您的合同是固定的,您可以通过以下方式启用此功能(如果我弄错了一点,请道歉 - 不是在 PC 上):

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

    当然,您以后可以随时将其更改为显式 [ProtoMember(n)] - 只需按照字母顺序成员布局使用 1、2、3 等,然后对您的 DTO 进行任何您想要的更改。

    【讨论】:

      猜你喜欢
      • 2016-11-09
      • 1970-01-01
      • 1970-01-01
      • 2018-04-30
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 2014-10-24
      相关资源
      最近更新 更多