我有一个工作的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
的作用。无论有没有,我都试过了......
答案 0 :(得分:1)
听起来我们想强迫它被排除在外;首先要尝试,您可以尝试在代码生成中使用“detectmissing”选项。这可以从IDE和命令行中进行,但不同(让我知道你正在使用哪些,我会添加更多)。
另一个类似的选择是添加(在部分类中)bool {memberName}Specified {get;set;}
。我现在正在查看一个涉及默认空字符串的奇怪的开放式报告。