我有一个通过 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
。有没有都试过了。。。