Protobuf嵌套BoolVal类型时False值未序列化问题(C#)
Protobuf布尔值序列化丢失问题分析
定义的Protobuf结构
message VenueCalibrationData { string sportType = 1; int64 lastModifiedCalibration = 2; BoolVal isPrimary = 3; } message BoolVal { bool value = 1; }
客户端接收日志
{ "venueDataCalibration": [ { "sportType": "BASEBALL", "lastModifiedCalibration": "1667988929", "isPrimary": { "value": true } }, { "sportType": "SOCCER", "lastModifiedCalibration": "1667988909", "isPrimary": { } } ] }
服务器赋值代码
venueCalibDataProto.IsPrimary = new BoolVal(); venueCalibDataProto.IsPrimary.Value = (folderName.ToLower() == primaryCalib.ToLower());
问题
服务器端通过venueCalibDataProto.IsPrimary.Value.ToString()能看到值为False,但客户端接收的isPrimary是空对象,原因是什么?
问题原因
Protobuf的默认序列化规则中,布尔类型的false属于默认值,如果字段值等于默认值,Protobuf会自动忽略该字段的序列化(目的是压缩传输数据体积)。当isPrimary.Value为false时,这个字段不会被序列化到输出内容中,因此客户端收到的isPrimary就是一个空对象。
解决办法
有两种常见处理方案:
- 修改Protobuf结构,强制序列化默认值:如果使用的是Proto3版本,在
BoolVal的value字段上添加optional修饰,让Protobuf即使字段为默认值也会序列化它:
若使用Proto2版本,可以给字段设置message BoolVal { optional bool value = 1; }default属性来显式保留默认值,但Proto3需要启用可选字段特性才能生效。 - 客户端兼容处理:在客户端解析时,约定空的
isPrimary对象对应value: false,无需修改服务端结构。
内容的提问来源于stack exchange,提问作者Yuki1112
相关产品推荐
相关产品推荐

