シリアライゼーションとデシリアライゼーションにprotobuf-netを使用していました。
私が従った方法は、RuntimeTypeModel を作成し、シリアル化する必要がある、またはシリアル化をサポートする必要があるすべての型を追加することです。すべてのタイプを追加したら、パフォーマンス上の利点のために TypeModel.Compile() を使用しています。
クラス インスタンスがシリアル化され、blob としてデータベースに保存されると、データベースからフェッチするときにそれを逆シリアル化できました。ただし、マシンを変更してデシリアライズしようとすると、トークン型の ArgumentException が発生します
at ProtoBuf.ProtoReader.EndSubItem(SubItemToken token, ProtoReader reader) in c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 584
at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 567
at ProtoBuf.ProtoReader.ReadObject(Object value, Int32 key, ProtoReader reader) in c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 543
at proto_157(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 57
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) in c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 783
at ProtoBuf.ProtoReader.ReadTypedObject(Object value, Int32 key, ProtoReader reader, Type type) in c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 556
at ProtoBuf.ProtoReader.ReadObject(Object value, Int32 key, ProtoReader reader) in c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 543
at proto_190(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 57
at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) in c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 783
at ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoReader reader, Type type, Object value, Boolean noAutoCreate) in c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 683
at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context) in c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 582
at ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type) in c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 561
コードベースは同じですが、別のマシンから実行すると、この問題が発生しました。
シリアル化に参加するクラスは非常に単純です
public class NetworkData
{
}
/// <summary>
/// Class for representing dashboard URL item
/// </summary>
public class DashboardURLItem : NetworkData
{
/// <summary>
/// Gets and Sets the URL
/// </summary>
public string URL { get; set; }
/// <summary>
/// Gets and Sets the Header for the URL Item
/// </summary>
public string Header { get; set; }
}
シリアル化のために、私は次のコードを使用しています
public byte[] SerializeData(T piclObjectData)
{
try
{
using (MemoryStream loclStream = new MemoryStream())
{
NWTypeModel.Serialize(loclStream, piclObjectData);
byte[] resultbuffer = new byte[loclStream.Length + 4]; // Those many bytes were generated in serialization + Message Length
Array.Copy(BitConverter.GetBytes(resultbuffer.Length), resultbuffer, 4);
Array.Copy(loclStream.GetBuffer(), 0, resultbuffer, 4, loclStream.Position);
return resultbuffer;
}
}
catch (Exception E)
{
Logger.WriteLog(ToString() + ": Exception while serializing - " + E.Message);
throw;
}
}
逆シリアル化のコード
public T DeSerializeData(byte[] piarBuffer)
{
try
{
using (MemoryStream loclStream = new MemoryStream())
{
loclStream.Seek(0, SeekOrigin.Begin);
loclStream.Write(piarBuffer, 4, piarBuffer.Length - 4); // 4 Bytes for Message length
loclStream.Seek(0, SeekOrigin.Begin);
return (T)NWTypeModel.Deserialize(loclStream, null, f_GenericType);
}
}
catch (Exception E)
{
Logger.WriteLog(ToString() + ": Exception while de-serializing - " + E.Message);
}
return null;
}
シリアル化と逆シリアル化はデータベースの同じマシンで正常に機能していましたが、別のマシンでデータベースから値を取得すると、逆シリアル化できません。
私が何か間違ったことをしている場合や、さらに何かを処理する必要がある場合は、光を投げてください.
ありがとう