使用protobuf-net时整数0被序列化为null的解决方案咨询
protobuf-net序列化0值整数被忽略的解决方案
首先明确该现象的根因:这是protobuf协议的标准设计,值为对应类型默认值的字段默认不会被写入序列化结果,反序列化时若未读取到对应字段,会自动为字段赋值为类型默认值;如果使用的是可空值类型(如int?),未读取到字段时就会赋值为null,也就是你观察到的现象。
可用的变通方案如下:
标记字段为必填
给对应字段的[ProtoMember]特性添加IsRequired = true参数,强制要求该字段无论值是否为默认值都必须序列化,反序列化时也会校验该字段必须存在。
示例代码:[ProtoContract] public class YourModel { // 第1个参数是字段序号,IsRequired设为true强制序列化 [ProtoMember(1, IsRequired = true)] public int TargetIntField { get; set; } }使用可空值类型声明字段
可空值类型(int?)的默认值为null而非0,此时赋值为0不属于默认值范围,会被正常序列化。只有当字段值为null时才会被忽略。
示例代码:[ProtoContract] public class YourModel { [ProtoMember(1)] public int? TargetIntField { get; set; } }显式修改字段的默认值
通过[DefaultValue]特性将字段的默认值设置为非0的其他值,此时0就不属于默认值范围,会被正常序列化。注意要同时给字段赋初始默认值和特性参数匹配。
示例代码:using System.ComponentModel; [ProtoContract] public class YourModel { [ProtoMember(1)] [DefaultValue(-1)] public int TargetIntField { get; set; } = -1; }全局开启默认值序列化
如果你需要全项目所有字段都保留默认值序列化,可以修改protobuf-net的全局运行时配置,开启SerializeDefaults参数即可。该方案会增大序列化后的数据体积,建议按需选择。
示例代码:using ProtoBuf.Meta; // 全局配置,所有字段无论是否为默认值都会被序列化 RuntimeTypeModel.Default.SerializeDefaults = true;
注意:以上方案均兼容标准protobuf协议,跨语言交互时无需接收方做特殊适配。
内容的提问来源于stack exchange,提问作者Raja Sinha
相关产品推荐
相关产品推荐

