protobuf-net中非必需字段的序列化

时间:2010-05-11 11:38:20

标签: c# protobuf-net protocol-buffers

我有一个工作的Java客户端,通过ProtoBuf序列化消息与Google通信。我目前正在尝试将该客户端转换为C#。

我有一个.proto文件,其中参数appId是一个可选字符串。它在protobuf-net库生成的C#表示中的默认值是一个空字符串,就像它在同一文件的java表示中一样。

message AppsRequest {
  optional AppType appType = 1;
  optional string query = 2;
  optional string categoryId = 3;
  optional string appId = 4;
  optional bool withExtendedInfo = 6;
}

我发现当我在Java客户端中明确地将appId设置为""时,客户端将停止工作(来自Google的403 Bad Request)。当我在java客户端中明确地将appId设置为null时,一切正常,但只是因为hasAppId被设置为false(我不确定它如何影响序列化)。

在C#客户端,我总是收到403个回复。我没有看到在设置值和设置默认值之间的区别背后的任何逻辑,这似乎在java客户端中产生了所有差异。由于输出始终是二进制流,我不确定成功的java消息是否使用空字符串序列化,或者根本没有序列化。

在C#客户端中,我尝试在IsRequired属性上将ProtoMember设置为true,强制它们序列化,我尝试将默认值设置为null,并显式设置"",所以我很确定我已尝试某些配置,其中值正在被序列化。我也玩过ProtoBuf.ProtoIgnore并且在某些时候完全删除appId参数,但我无法避免C#中的403错误。

我尝试从java手动复制序列化字符串,这解决了我的问题,所以我确定HTTP请求的其余部分正常工作,并且错误可以追溯到序列化对象。

我的序列化就是这样:

var clone = ProtoBuf.Serializer.DeepClone(request);

MemoryStream ms = new MemoryStream(2000);
ProtoBuf.Serializer.Serialize(ms, clone);

var bytearr = ms.ToArray();
string encodedData = Convert.ToBase64String(bytearr);

我承认不太确定DeepClone的作用。无论有没有,我都试过了......

1 个答案:

答案 0 :(得分:1)

听起来我们想强迫它被排除在外;首先要尝试,您可以尝试在代码生成中使用“detectmissing”选项。这可以从IDE和命令行中进行,但不同(让我知道你正在使用哪些,我会添加更多)。

另一个类似的选择是添加(在部分类中)bool {memberName}Specified {get;set;}。我现在正在查看一个涉及默认空字符串的奇怪的开放式报告。