新MemoryStream中protobuf.net中的线型错误无效

时间:2013-06-06 00:54:36

标签: c# protocol-buffers protobuf-net

我正在尝试解析从外部服务收到的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 ==

现在,当我运行程序时,反序列化时出现无效的线型错误。我看不出有什么理由会发生这种情况。我错过了一些明显的东西吗?

2 个答案:

答案 0 :(得分:2)

这通常意味着:

  • 二进制文件无效(people make a mess of binary all the time;如果需要以字符串形式存储/传输,则使用base-64完全没问题。
  • 数据不匹配(例如,数据中的字段2varint,但类型中为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); } 方法)

所以:如果这不适合你,重要的两个问题是:

  • 是运行时真实代码中的实际 base-64吗?或者这就是你认为理论上应该是什么
  • 你的DeserializeFromBytes课程是什么样的?

答案 1 :(得分:1)

编辑:正如Marc Gravell在评论中指出的那样,我走错了路。请忽略我的答案,但由于评论讨论很有价值,我将其离开。

protobuf-net与protobuf不同,并且不以统一的,跨平台兼容的方式遵循算法。 protobuf-net是一个基于.NET协议的序列化器,碰巧使用protobuf,但为了互操作的目的,没有实现protobuf“to spec”。例如:protobuf-net知道.NET类型,而Google的protobuf不知道.NET类型。有关更多信息,请参阅此链接:

http://code.google.com/p/protobuf-net/wiki/GettingStarted