我一直在使用 protobuf-net 通过网络发送一些对象,直到现在一切都运行良好。但是,我遇到了我的类的一个特定实例,它在单声道下运行时无法反序列化。完全相同的对象反序列化在 .net 下正确运行。byte[]
我已经通过检查 md5 总和验证了当我在单声道和 .net 下运行时通过电线接收到的数据完全相同。这表明问题必须与 protobuf-net 反序列化有关。这是我用来反序列化的代码byte[]
:
using (MemoryStream ms = new MemoryStream(serializedByteArray))
{
return (MyProtoBufDto)Serializer.Deserialize<MyProtoBufDto>(ms);
}
这是我得到的例外:
System.IO.EndOfStreamException: Failed to read past end of stream.
at ProtoBuf.ProtoReader.Ensure (int,bool) <0x00167>
at ProtoBuf.ProtoReader.ReadString () <0x0005b>
at (wrapper dynamic-method) System.Collections.Generic.KeyValuePair`2<string, string>.proto_18 (object,ProtoBuf.ProtoReader) <0x000c8>
at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read (object,ProtoBuf.ProtoReader) <0x0002d>
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize (int,object,ProtoBuf.ProtoReader) <0x00112>
at ProtoBuf.ProtoReader.ReadTypedObject (object,int,ProtoBuf.ProtoReader,System.Type) <0x00056>
at ProtoBuf.ProtoReader.ReadObject (object,int,ProtoBuf.ProtoReader) <0x0001b>
at (wrapper dynamic-method) System.Collections.Generic.KeyValuePair`2<string, System.Collections.Generic.List`1<System.Collections.Generic.KeyValuePair`2<string, string>>>.proto_16 (object,ProtoBuf.ProtoReader) <0x00220>
at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read (object,ProtoBuf.ProtoReader) <0x0002d>
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize (int,object,ProtoBuf.ProtoReader) <0x00112>
at ProtoBuf.ProtoReader.ReadTypedObject (object,int,ProtoBuf.ProtoReader,System.Type) <0x00056>
at ProtoBuf.ProtoReader.ReadObject (object,int,ProtoBuf.ProtoReader) <0x0001b>
at (wrapper dynamic-method) MyGroupDto.proto_14 (object,ProtoBuf.ProtoReader) <0x001bc>
at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read (object,ProtoBuf.ProtoReader) <0x0002d>
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize (int,object,ProtoBuf.ProtoReader) <0x00112>
at ProtoBuf.ProtoReader.ReadTypedObject (object,int,ProtoBuf.ProtoReader,System.Type) <0x00056>
at ProtoBuf.ProtoReader.ReadObject (object,int,ProtoBuf.ProtoReader) <0x0001b>
at (wrapper dynamic-method) System.Collections.Generic.KeyValuePair`2<MyGroupNameDto, MyGroupDto>.proto_12 (object,ProtoBuf.ProtoReader) <0x00197>
at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read (object,ProtoBuf.ProtoReader) <0x0002d>
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize (int,object,ProtoBuf.ProtoReader) <0x00112>
at ProtoBuf.ProtoReader.ReadTypedObject (object,int,ProtoBuf.ProtoReader,System.Type) <0x00056>
at ProtoBuf.ProtoReader.ReadObject (object,int,ProtoBuf.ProtoReader) <0x0001b>
at (wrapper dynamic-method) MyResultProtoBufDto.proto_8 (object,ProtoBuf.ProtoReader) <0x002b9>
at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read (object,ProtoBuf.ProtoReader) <0x0002d>
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize (int,object,ProtoBuf.ProtoReader) <0x00112>
at ProtoBuf.ProtoReader.ReadTypedObject (object,int,ProtoBuf.ProtoReader,System.Type) <0x00056>
at ProtoBuf.ProtoReader.ReadObject (object,int,ProtoBuf.ProtoReader) <0x0001b>
at (wrapper dynamic-method) MyProtoBufDto.proto_6 (object,ProtoBuf.ProtoReader) <0x00116>
at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read (object,ProtoBuf.ProtoReader) <0x0002d>
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize (int,object,ProtoBuf.ProtoReader) <0x00112>
at ProtoBuf.Meta.TypeModel.DeserializeCore (ProtoBuf.ProtoReader,System.Type,object,bool) <0x0005b>
at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream,object,System.Type,ProtoBuf.SerializationContext) <0x00097>
at ProtoBuf.Meta.TypeModel.Deserialize (System.IO.Stream,object,System.Type) <0x0001f>
at ProtoBuf.Serializer.Deserialize<MyProtoBufDto> (System.IO.Stream) <0x00033>
at MyClient.Serialization.ProtoBufSerialization.DecompressAndDeserialize<MyProtoBufDto> (byte[]) <0x0008b>
我已经尝试过单声道 2.10.9 和最新的单声道 3.2.3 并且收到了同样的异常。我正在使用最新的 protobuf-net dll 版本(2.0.0.666)。我尝试了 protobuf-net-mono 目录中的 dll(用单声道编译器编译?)和常规的 .net 编译版本,但在单声道下运行时不断收到此异常。
课程详情MyProtoBufDto
:
[DataContract]
public class MyProtoBufDto
{
[DataMember(Order = 1)]
public List<MyResultProtoBufDto> Result { get; set; }
}
[DataContract]
public class MyResultProtoBufDto
{
[DataMember(Order = 1)]
public Dictionary<MyGroupNameDto, MyGroupDto> Groups { get; set; }
}
[DataContract]
public class MyGroupDto
{
[DataMember(Order = 1)]
public Dictionary<string, List<KeyValuePair<string, string>>> Group { get; set; }
}
MyGroupNameDto
只是一个enum
更多信息: 这是在 linux 上使用单声道。我还没有在 Windows 上测试过单声道。我验证了 byte[] 离线和解压后的 byte[] 在单声道和 Windows 下是相同的,因此我们应该向 protobuf-net 提供相同的确切数据。
更新 我们在服务器端进行了更改,以始终从已序列化的对象中删除空集合,此后未遇到此错误。我知道 protobuf 没有区分空集合和空集合,但奇怪的是,mono 与 .net 上的行为以某种方式有所不同,并引发了此错误。