You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 02:00:06