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

发布于 2024-09-01 19:14:38 字数 1413 浏览 8 评论 0原文

我有一个正在运行的 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# 客户端中,我尝试将 ProtoMember 属性上的 IsRequired 设置为 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 的作用。我已经尝试过有和没有它......

I have a working java client that is communicating with Google, through ProtoBuf serialized messages. I am currently trying to translate that client into C#.

I have a .proto file where the parameter appId is an optional string. Its default value in the C# representation as generated by the protobuf-net library is an empty string, just as it is in the java representation of the same file.

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

I find that when I explicitly set appId to "" in the java client, the client stops working (403 Bad Request from Google). When I explicitly set appId to null in the java client, everything works, but only because hasAppId is being set to false (I'm uncertain as to how that affects the serialization).

In the C# client, I always get 403 responses. I don't see any logic behind the distinction between not setting a value, and setting the default value, that seems to make all the difference in the java client. Since the output is always a binary stream, I am not sure if the successful java messages are being serialized with an empty string, or not serialized at all.

In the C# client, I've tried setting IsRequired to true on the ProtoMember attribute, to force them to serialize, and I've tried setting the default value to null, and explicitly set "", so I'm quite sure I've tried some configuration where the value is being serialized. I've also played around with ProtoBuf.ProtoIgnore and at some point, removing the appId parameter altogether, but I haven't been able to avoid the 403 errors in C#.

I've tried manually copying the serialized string from java, and that resolved my issues, so I'm certain that the rest of the HTTP Request is working, and the error can be traced to the serialized object.

My serialization is simply this:

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);

I'll admit to not being quite sure about what DeepClone does. I've tried both with and without it...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

菊凝晚露 2024-09-08 19:14:38

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

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

It sounds like we want to force it to be excluded; for a first thing to try, you could try using the "detectmissing" option in the code-generation. This is possible from the IDE and command-line, but differently (let me know which you are using and I'll add more).

Another similar option is to add (in a partial class) a bool {memberName}Specified {get;set;}. There is an existing open report of an oddity involving default empty strings, that I am looking at.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文