I'm trying to parse a protobuf message received from an external service. I know that this data is a valid protobuf message, and I know I'm not accidentally mangling it before I send it to the deserializer. Here's my code:
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;
}
and I'm calling this method like this:
MercuryReply header = ProtobufUtils.DeserializeFromBytes<MercuryReply>(Convert.FromBase64String(metadata[0]));
metadata[0]
is a base64 string that includes a protobuf message. A sample looks something like this:
CjRobTovL21ldGFkYXRhL2FsYnVtL2M1MzU3MTA0M2U4ODQ3YjRhODc1YzVlNmZiNmNiZTdmEhp2bmQuc3BvdGlmeS9tZXRhZGF0YS1hbGJ1bSCQAzIYCgpNRC1WZXJzaW9uEgoxMzcwMzc5NTA1Mg8KBk1DLVRUTBIFNjk2MDQyGQoPTUMtQ2FjaGUtUG9saWN5EgZwdWJsaWMyDwoHTUMtRVRhZxIELD8q+Q==
Now, when I run the program, I get an Invalid wire-type error when deserializing. I can't see any reason why this would be happening. Is there something obvious here that I missed?
That usually means either:
2
is varint
in the data, but is a string
in the type)Based on you binary, I've pieced together that MercuryReply
might look something like:
[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>();
}
(the names here are pure guesswork based on what the data looks like; protobuf does not transmit names - only the numeric keys, i.e. 1
/2
/4
/6
in this example)
which works fine when tested with:
static void Main()
{
var encoded = Convert.FromBase64String("CjRobTovL21ldGFkYXRhL2FsYnVtL2M1MzU3MTA0M2U4ODQ3YjRhODc1YzVlNmZiNmNiZTdmEhp2bmQuc3BvdGlmeS9tZXRhZGF0YS1hbGJ1bSCQAzIYCgpNRC1WZXJzaW9uEgoxMzcwMzc5NTA1Mg8KBk1DLVRUTBIFNjk2MDQyGQoPTUMtQ2FjaGUtUG9saWN5EgZwdWJsaWMyDwoHTUMtRVRhZxIELD8q+Q==");
MercuryReply header = ProtobufUtils.DeserializeFromBytes<MercuryReply>(encoded);
}
(using your DeserializeFromBytes
method)
So: if that isn't working for you, the important two questions are:
MercuryReply
class look like?