我正在尝试解析从外部服务收到的protobuf消息。我知道这个数据是一个有效的protobuf消息,我知道在将它发送到解串器之前我不会意外地修改它。这是我的代码:
public static T DeserializeFromBytes<T>(byte[] encoded)
{
MemoryStream stream = new MemoryStream(encoded);
stream.SetLength(encoded.Length);
stream.Capacity = encoded.Length;
T decoded = (T)Serializer.Deserialize<T>(stream);
stream.Close();
return decoded;
}
我正在调用这个方法:
MercuryReply header = ProtobufUtils.DeserializeFromBytes<MercuryReply>(Convert.FromBase64String(metadata[0]));
metadata[0]
是一个包含protobuf消息的base64字符串。示例看起来像这样:
CjRobTovL21ldGFkYXRhL2FsYnVtL2M1MzU3MTA0M2U4ODQ3YjRhODc1YzVlNmZiNmNiZTdmEhp2bmQuc3BvdGlmeS9tZXRhZGF0YS1hbGJ1bSCQAzIYCgpNRC1WZXJzaW9uEgoxMzcwMzc5NTA1Mg8KBk1DLVRUTBIFNjk2MDQyGQoPTUMtQ2FjaGUtUG9saWN5EgZwdWJsaWMyDwoHTUMtRVRhZxIELD8q + Q ==
现在,当我运行程序时,反序列化时出现无效的线型错误。我看不出有什么理由会发生这种情况。我错过了一些明显的东西吗?
答案 0 :(得分:2)
这通常意味着:
2
为varint
,但类型中为string
基于你的二进制文件,我拼凑了MercuryReply
看起来像:
[ProtoContract]
public class MercuryReply
{
[ProtoMember(1)]
public string Location { get; set; }
[ProtoMember(2)]
public string ContentType { get; set; }
[ProtoMember(4)]
public int ResponseStatus { get; set; }
[ProtoMember(6)]
public Dictionary<string, string> Headers { get { return headers; } }
private readonly Dictionary<string, string> headers
= new Dictionary<string, string>();
}
(这里的名字是基于数据的纯粹猜测; protobuf不传输名称 - 只有数字键,即1
/ 2
/ 4
/ {{ 1}}在这个例子中)
使用
进行测试时正常6
(使用static void Main()
{
var encoded = Convert.FromBase64String("CjRobTovL21ldGFkYXRhL2FsYnVtL2M1MzU3MTA0M2U4ODQ3YjRhODc1YzVlNmZiNmNiZTdmEhp2bmQuc3BvdGlmeS9tZXRhZGF0YS1hbGJ1bSCQAzIYCgpNRC1WZXJzaW9uEgoxMzcwMzc5NTA1Mg8KBk1DLVRUTBIFNjk2MDQyGQoPTUMtQ2FjaGUtUG9saWN5EgZwdWJsaWMyDwoHTUMtRVRhZxIELD8q+Q==");
MercuryReply header = ProtobufUtils.DeserializeFromBytes<MercuryReply>(encoded);
}
方法)
所以:如果这不适合你,重要的两个问题是:
DeserializeFromBytes
课程是什么样的?答案 1 :(得分:1)
protobuf-net与protobuf不同,并且不以统一的,跨平台兼容的方式遵循算法。 protobuf-net是一个基于.NET协议的序列化器,碰巧使用protobuf,但为了互操作的目的,没有实现protobuf“to spec”。例如:protobuf-net知道.NET类型,而Google的protobuf不知道.NET类型。有关更多信息,请参阅此链接: