c# protobuf-net

c# - Protobuf-net: intento leer más allá del final de la transmisión



(1)

He visto este error cuando el "tipo" que especifico para deserializar no es el mismo que el tipo original que se serializó. Supongo que esto también podría suceder si su objeto ha cambiado y está intentando deserializar una versión anterior de su objeto (es decir, una matriz de bytes antigua) que es incompatible con la nueva versión.

Nuestro sistema, al serializar un mensaje utilizando protobuf-net, a veces, pero no siempre, genera el error expuesto a continuación. ¿Cuáles son las razones del error y cómo puedo mitigarlo?

Tenga en cuenta que ya estamos utilizando DeserializeWithLengthPrefix .

ACTUALIZACIÓN: el código correspondiente está aquí.

private const PrefixStyle PrefixStyleInPlace = PrefixStyle.Fixed32; public static byte[] SerializeObjectToByteArray<TSerializable>(TSerializable source) where TSerializable : class { byte[] result; using (var memoryStream = SerializeObjectToStream(source)) { result = memoryStream.ToArray(); } return result; } public static TResult DeserializeObject<TResult>(byte[] source) { TResult result; using (var memoryStream = new MemoryStream(source)) { memoryStream.Position = 0; result = Serializer.DeserializeWithLengthPrefix<TResult>(memoryStream,PrefixStyleInPlace); } return result; } public static MemoryStream SerializeObjectToStream<TSerializable>(TSerializable source) where TSerializable : class { var memoryStream = new MemoryStream(); Serializer.SerializeWithLengthPrefix(memoryStream, source,PrefixStyleInPlace); memoryStream.Position = 0; return memoryStream; } public static TResult DeserializeObject<TResult>(MemoryStream sourceStream) { TResult result; result = DeserializeObject<TResult>(sourceStream.ToArray()); return result; }

MENSAJE :

System.IO.EndOfStreamException : Attempted to read past the end of the stream. +++++++++++++++++++ STACK TRACE: at ProtoBuf.ProtoReader.Ensure(Int32 count, Boolean trict) in c:/Dev/protobuf-net/protobuf-net/ProtoReader.cs:line 234 at ProtoBuf.ProtoReader.ReadString() in c:/Dev/protobuf-net/protobuf-net/ProtoReader.cs:line 471 at proto_15(Object , ProtoReader ) at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Serializers/CompiledSerializer.cs:line 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Meta/RuntimeTypeModel.cs:line 721 at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in c:/Dev/protobuf-net/protobuf-net/ProtoReader.cs:line 556 at proto_16(Object , ProtoReader ) at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Serializers/CompiledSerializer.cs:line 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Meta/RuntimeTypeModel.cs:line 721 at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in c:/Dev/protobuf-net/protobuf-net/ProtoReader.cs:line 556 at proto_11(Object , ProtoReader ) at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Serializers/CompiledSerializer.cs:line 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Meta/RuntimeTypeModel.cs:line 721 at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in c:/Dev/protobuf-net/protobuf-net/ProtoReader.cs:line 556 at proto_16(Object , ProtoReader ) at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Serializers/CompiledSerializer.cs:line 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Meta/RuntimeTypeModel.cs:line 721 at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in c:/Dev/protobuf-net/protobuf-net/ProtoReader.cs:line 556 at proto_13(Object , ProtoReader ) at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Serializers/CompiledSerializer.cs:line 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Meta/RuntimeTypeModel.cs:line 721 at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in c:/Dev/protobuf-net/protobuf-net/ProtoReader.cs:line 556 at proto_16(Object , ProtoReader ) at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Serializers/CompiledSerializer.cs:line 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Meta/RuntimeTypeModel.cs:line 721 at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in c:/Dev/protobuf-net/protobuf-net/ProtoReader.cs:line 556 at proto_2(Object , ProtoReader ) at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Serializers/CompiledSerializer.cs:line 49 at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) in c:/Dev/protobuf-net/protobuf-net/Meta/RuntimeTypeModel.cs:line 721 at ProtoBuf.Meta.TypeModel.DeserializeWithLengthPrefix(Stream source, Object value, Type type, PrefixStyle style, Int32 expectedField, TypeResolver resolver, Int32& bytesRead, Boolean& haveObject, SerializationContext context) in c:/Dev/protobuf-net/protobuf-net/Meta/TypeModel.cs:line 351 at ProtoBuf.Serializer.DeserializeWithLengthPrefix[T](Stream source, PrefixStyle style, Int32 fieldNumber) in c:/Dev/protobuf-net/protobuf-net/Serializer.cs:line 303 at ProtoBuf.Serializer.DeserializeWithLengthPrefix[T](Stream source, PrefixStyle style) in c:/Dev/protobuf-net/protobuf-net/Serializer.cs:line 288 at ermeX.Common.ObjectSerializer.DeserializeObject[TResult](Byte[] source) in [ProtoContract(SkipConstructor = true)] [ProtoInclude(100, typeof(BusMessage))] [ProtoInclude(200, typeof(TransportMessage))] [ProtoInclude(300, typeof(BizMessage))]

Codifique aqui

internal abstract class SystemMessage : ISystemMessage, IEquatable<SystemMessage> { protected SystemMessage():this(Guid.NewGuid(),DateTime.UtcNow) { } protected SystemMessage(Guid messageId,DateTime createdTimeUtc) { MessageId = messageId; CreatedTimeUtc = new DateTime(createdTimeUtc.Ticks);//TODO: UNTIL PROTOBUF-NET FIXES ISSUE 335 } [ProtoMember(1)] public Guid MessageId{get;private set;} [ProtoMember(2)] public DateTime CreatedTimeUtc { get; private set; } ... } [ProtoContract(SkipConstructor = true)] internal sealed class TransportMessage : SystemMessage, ISystemMessage<BusMessage> { //just for the serializer, remove in the future private TransportMessage() { } public TransportMessage(Guid recipient, BusMessage data) : this(data.MessageId, data.CreatedTimeUtc, recipient, data) { } public TransportMessage(Guid messageId, DateTime createdTimeUtc, Guid recipient, BusMessage data) : base(messageId, createdTimeUtc) { if (data == null) throw new ArgumentNullException("data"); if (recipient.IsEmpty()) throw new ArgumentException("recipient cannot be an empty value"); Recipient = recipient; Data = data; } [ProtoMember(1)] public Guid Recipient { get; private set; } [ProtoMember(2)] public BusMessage Data { get; private set; } } [ProtoContract(SkipConstructor = true)] internal sealed class BusMessage: SystemMessage, ISystemMessage<BizMessage>,IEquatable<BusMessage> { private BusMessage() { } public BusMessage(Guid publisher,BizMessage data) : this(data.MessageId,data.CreatedTimeUtc,publisher, data) { } public BusMessage(Guid messageId, DateTime createdTimeUtc, Guid publisher, BizMessage data) : base(messageId,createdTimeUtc) { if (data == null) throw new ArgumentNullException("data"); Publisher = publisher; Data = data; } [ProtoMember(1)] public Guid Publisher { get; protected set; } [ProtoMember(2)] public BizMessage Data { get; protected set; } } [ProtoContract(SkipConstructor = true)] internal sealed class BizMessage : SystemMessage, IEquatable<BizMessage> { private string _jsonMessage; private object _data = null; public BizMessage(object data) : base() { if (data == null) throw new ArgumentNullException("data"); _data = data; } private BizMessage(){} public static BizMessage FromJson(string jsonData) { if(string.IsNullOrEmpty(jsonData)) throw new ArgumentException(); return new BizMessage(){JsonMessage = jsonData}; } [ProtoMember(75)] internal string JsonMessage { get { if(string.IsNullOrEmpty(_jsonMessage)) { if (_data == null) throw new ApplicationException( "One of both, _data or the serialized json message must have a value"); _jsonMessage = JsonSerializer.SerializeObjectToJson(_data); } return _jsonMessage; } private set { _jsonMessage = value; } } public Type MessageType { get { UpdateData(); if (_data == null) return typeof(void); return _data.GetType(); } } public object RawData { get { UpdateData(); return _data; } } private void UpdateData() { if (_data == null) { if (string.IsNullOrEmpty(_jsonMessage)) throw new ApplicationException( "One of both, _data or the serialized json message must have a value"); _data = JsonSerializer.DeserializeObjectFromJson<object>(_jsonMessage); } } }