【发布时间】:2020-03-03 11:00:30
【问题描述】:
所以我有一条来自不同服务的 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(UnknownFieldSet unknownFields,CodedInputStream 输入)在 Messages.RecordingStatusChangeMessage.MergeFrom(CodedInputStream 输入)在 C:\Users\iliaar\go\src\RecorderApp\testers\NewRecorderTester\Infra.AppDataManager\Model\Protos\Pubsub\messages.pb.cs:line 3259 在 ClusterRecordersModule.RecordersViewModel.OnNewMessage(消息 消息)在 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_transition:“2020-03-03T12:29:59.531473957Z” 信号转换:“2020-03-03T12:29:59.531473589Z”
【问题讨论】:
-
这里真正的问题是:
Msg的有效载荷真的有效吗?我猜它不是,但要对此进行测试,请将有效负载内容获取为十六进制:var hex = BitConverter.ToString(message.Msg.ToByteArray())(并在某处写入hex- 到控制台很好),然后通过@987654321 运行该十六进制@ - 如果验证者同意数据无效:数据无效,你需要做的是修复数据的来源 -
我认为内容很好,因为在源服务中反序列化它可以正常工作。十六进制验证器也没有指定任何错误
-
那很奇怪;我不知道您的数据/有效负载在这里有多敏感;您能否分享
InnerMessageObject的有效负载和架构,以便我们提供更多帮助? (上下文:我是那个验证器站点的作者;我非常了解协议) -
是的,我现在正在编辑主要问题
标签: c# deserialization protocol-buffers