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

问题描述 投票:1回答:1

因此,我有一条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字段时,我不断收到此错误:

协议消息包含具有无效电线类型的标签。

和堆栈跟踪

在Google.Protobuf.UnknownFieldSet.MergeFieldFrom(CodedInputStream输入)Google.Protobuf.UnknownFieldSet.MergeGroupFrom(CodedInputStream输入)在Google.Protobuf.CodedInputStream.ReadGroup(Int32 fieldNumber,UnknownFieldSet设置)Google.Protobuf.UnknownFieldSet.MergeFieldFrom(CodedInputStream输入)在Google.Protobuf.UnknownFieldSet.MergeFieldFrom(UnknownFieldSetunknownFields,CodedInputStream输入)在Messages.RecordingStatusChangeMes​​sage.MergeFrom(CodedInputStream输入)C:\ Users \ iliaar \ go \ src \ RecorderApp \ testers \ NewRecorderTester \ Infra.AppDataManager \ Model \ Protos \ Pubsub \ messages.pb.cs:line3259点ClusterRecordersModule.RecordersViewModel.OnNewMessage(消息讯息)C:\ Users \ iliaar \ go \ src \ RecorderApp \ testers \ NewRecorderTester \ ClusterRecordersModule \ ViewModels \ RecordersViewModel.cs:line154

我尝试调用新对象的几种方法,但都失败了例如,我尝试使用现有实例并合并:

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_transition:“ 2020-03-03T12:29:59.531473957Z”signal_transition:“ 2020-03-03T12:29:59.531473589Z”

c# deserialization protocol-buffers bytestring
1个回答
0
投票

您的有效载荷不是protobuf。如果通过this validator进行尝试,则会看到:

63 =字段12,键入StartGroup

错误:无效的电线类型;这通常意味着您已覆盖文件而没有截断或设置长度;参见Using Protobuf-net, I suddenly got an exception about an unknown wire-type

因此,让我们看一下前两个字节,就像它们是protobuf一样-解码器告诉我们0x63是什么意思;下一个字节0x6F应该是字段标头(“标记”);二进制形式是01101111,它是“ field 13,wire-type 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。

© www.soinside.com 2019 - 2024. All rights reserved.