2

我有一个通过 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)。appId当我在 java 客户端中明确设置null为时,一切正常,但只是因为hasAppId设置为 false(我不确定这如何影响序列化)。

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

在 C# 客户端中,我尝试将属性设置IsRequired为 trueProtoMember以强制它们进行序列化,并且我尝试将默认值设置为 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。有没有都试过了。。。

4

1 回答 1

1

听起来我们想强制将其排除在外;首先,您可以尝试在代码生成中使用“detectmissing”选项。这可以通过 IDE 和命令行实现,但有所不同(让我知道您使用的是哪个,我会添加更多内容)。

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

于 2010-05-11T12:06:50.457 回答