ProtoBuf-net反序列化后ROW_VERSION与PrimaryKeyId值为null的问题排查
问题原因排查
- ProtoBuf-net 是契约优先的序列化库,仅会序列化显式标记了
[ProtoMember]特性的成员;而原 BinaryFormatter 基于反射自动序列化字段/属性,无需显式标记。如果基类PrimaryKeyObject、TrackingObject中的PrimaryKeyId、ROW_VERSION未添加 ProtoBuf 序列化标记,这些字段会被忽略,导致反序列化后值为 null。 - 若基类位于独立的
Core.Shared库中,可能未引入 ProtoBuf-net 依赖或未对基类成员做序列化配置,派生类继承后自然无法携带这些基类字段参与序列化流程。
解决方案
方案1:直接修改基类添加序列化标记
如果有权限修改 Core.Shared 库的基类代码,给目标属性添加 [ProtoMember] 特性(注意标记的编号需唯一,同一类中不能重复):
// PrimaryKeyObject 基类修改 using ProtoBuf; public abstract class PrimaryKeyObject { [ProtoMember(1)] // 唯一编号,可根据实际调整 public Guid PrimaryKeyId { get; set; } } // TrackingObject 基类修改 public abstract class TrackingObject { [ProtoMember(2)] // 唯一编号,可根据实际调整 public byte[] ROW_VERSION { get; set; } }
方案2:通过 RuntimeTypeModel 动态配置(无需修改基类)
如果无法修改基类代码,可在序列化初始化阶段,通过 ProtoBuf-net 的 RuntimeTypeModel 动态注册基类的序列化规则:
using ProtoBuf; // 在应用启动或序列化工具初始化时执行 RuntimeTypeModel.Default.Add(typeof(PrimaryKeyObject), false) .Add(1, nameof(PrimaryKeyObject.PrimaryKeyId)); RuntimeTypeModel.Default.Add(typeof(TrackingObject), false) .Add(2, nameof(TrackingObject.ROW_VERSION));
额外验证点
- 确认
PrimaryKeyId、ROW_VERSION是公共可读写属性(get/set 都需存在),ProtoBuf-net 默认无法序列化只读属性或私有字段(除非额外配置字段)。 - 若
ROW_VERSION是私有字段驱动的属性,可直接标记字段:// 以 TrackingObject 为例 public abstract class TrackingObject { [ProtoMember(2)] private byte[] _rowVersion; public byte[] ROW_VERSION => _rowVersion; // 确保有设置逻辑,或配置 ProtoBuf 直接序列化字段 }
内容的提问来源于stack exchange,提问作者Pradeep
相关产品推荐
相关产品推荐

