gpt4 book ai didi

c# - 使用 C# Google.Protobuf 将 ByteString 反序列化为对象

转载 作者:行者123 更新时间:2023-12-04 10:28:50 30 4
gpt4 key购买 nike

所以我有一个来自不同服务的 gRPC 消息(用另一种编程语言编写)。
这是这个对象的一个​​迷你版本(显然真正的一个是由 protobuf 生成的)

public class Message
{
public string Topic { get; set; }
public string Identifier { get; set; }
public Google.Protobuf.ByteString Msg { get; set; }
}

我的问题是 ByteString 应该反序列化为另一个对象(也在 protobuf 文件中定义),但是当我尝试反序列化 Msg 字段时,我不断收到此错误:

Protocol message contained a tag with an invalid wire type.



和堆栈跟踪

at Google.Protobuf.UnknownFieldSet.MergeFieldFrom(CodedInputStream input) at Google.Protobuf.UnknownFieldSet.MergeGroupFrom(CodedInputStream input) at Google.Protobuf.CodedInputStream.ReadGroup(Int32 fieldNumber, UnknownFieldSet set) at Google.Protobuf.UnknownFieldSet.MergeFieldFrom(CodedInputStream input) at Google.Protobuf.UnknownFieldSet.MergeFieldFrom(UnknownFieldSet unknownFields, CodedInputStream input) at Messages.RecordingStatusChangeMessage.MergeFrom(CodedInputStream input) in C:\Users\iliaar\go\src\RecorderApp\testers\NewRecorderTester\Infra.AppDataManager\Model\Protos\Pubsub\messages.pb.cs:line 3259 at ClusterRecordersModule.RecordersViewModel.OnNewMessage(Message message) in C:\Users\iliaar\go\src\RecorderApp\testers\NewRecorderTester\ClusterRecordersModule\ViewModels\RecordersViewModel.cs:line 154



我尝试调用新对象的几个方法,但都失败了
例如,我尝试使用现有实例并合并如下:
innerMessageObject.MergeFrom(message.Msg.CreateCodedInput());

或使用静态解析器,如:
InnerMessageObject.Parser.ParseFrom(message.Msg.ToByteArray());

并且都因相同的错误而失败,堆栈跟踪最终收敛到 Google.Protobuf 库中的同一位置。
我的库版本是 8.1.0,我也尝试降级到版本 6

我真的很感激一些帮助。
谢谢

编辑:
innerMessage 对象的结构如下:
public class InnerMessageObject
{
public string ConfigID { get; set; }
public bool Storage { get; set; }
public bool Signal { get; set; }
public string StorageTransition { get; set; }
public string SignalTransition { get; set; }
}

此外,转换为十六进制会导致以下(有效)输出
63-6F-6E-66-69-67-5F-69-64-3A-20-37-32-30-62-66-65-34-39-2D-64-62-32-39-2D-34-35-38-33-2D-39-66-65-31-2D-65-30-32-30-37-33-32-37-39-37-39-34-0A-73-74-6F-72-61-67-65-3A-20-66-61-6C-73-65-0A-73-69-67-6E-61-6C-3A-20-66-61-6C-73-65-0A-73-74-6F-72-61-67-65-5F-74-72-61-6E-73-69-74-69-6F-6E-3A-20-22-32-30-32-30-2D-30-33-2D-30-33-54-31-32-3A-32-36-3A-34-31-2E-33-32-37-34-30-34-33-5A-22-0A-73-69-67-6E-61-6C-5F-74-72-61-6E-73-69-74-69-6F-6E-3A-20-22-32-30-32-30-2D-30-33-2D-30-33-54-31-32-3A-32-36-3A-34-31-2E-33-32-37-34-30-33-32-33-31-5A-22-0A

此外,将字节数组转换为字符串会产生具有正确数据的对象的字符串表示
var ba = pubsubMessage.Msg.ToByteArray();
return Encoding.UTF8.GetString(ba);

config_id: 720bfe49-db29-4583-9fe1-e02073279794 storage: false signal: false storage_transition: "2020-03-03T12:29:59.531473957Z" signal_transition: "2020-03-03T12:29:59.531473589Z"

最佳答案

您的有效载荷 不是 protobuf .如果我们尝试通过 this validator , 我们看:

63 = field 12, type StartGroup

error: Invalid wire-type; this usually means you have over-written a file without truncating or setting the length; see Using Protobuf-net, I suddenly got an exception about an unknown wire-type



所以让我们看看前两个字节,就好像它们是 protobuf 一样——解码器告诉我们 0x63 是什么意思;下一个字节 0x6F 应该是一个字段头(“标签”);在二进制中,这是 01101111,这将是“字段 13,线类型 7”;那里 protobuf 中没有线类型 7 .所以;解码器正确:有效载荷无效。

但并不是所有的都丢失了!

如果我们从所有这些 0x6* 值中猜测这可能是 ASCII 或 UTF8,并对其进行解码,我们会得到:
config_id: 720bfe49-db29-4583-9fe1-e02073279794
storage: false
signal: false
storage_transition: "2020-03-03T12:26:41.3274043Z"
signal_transition: "2020-03-03T12:26:41.327403231Z"

这似乎是一些粗略的基于行的标记化格式的数据。但是:不是protobuf。

关于c# - 使用 C# Google.Protobuf 将 ByteString 反序列化为对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60505749/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com