【发布时间】:2010-05-11 11:38:20
【问题描述】:
我有一个通过 ProtoBuf 序列化消息与 Google 通信的有效 Java 客户端。我目前正在尝试将该客户端翻译成 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# 客户端中,我尝试在 ProtoMember 属性上将 IsRequired 设置为 true,以强制它们进行序列化,并且我尝试将默认值设置为 null,并显式设置 "",所以我很确定我已经尝试了 some 正在序列化值的配置。我也玩过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 做了什么。有没有都试过了……
【问题讨论】:
标签: c# protobuf-net protocol-buffers