gpt4 book ai didi

c# - 使用 binaryformatter 反序列化

转载 作者:太空宇宙 更新时间:2023-11-03 23:37:14 26 4
gpt4 key购买 nike

我有一个序列化对象并通过网络发送它的程序:

TcpClient client = new TcpClient();
client.ReceiveTimeout = 10000;
client.SendTimeout = 10000;
IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888);
client.Connect(serverEndPoint);

BinaryFormatter binaryformatter = new BinaryFormatter();

NetworkStream networkStream = client.GetStream();
if (networkStream.CanWrite)
{
binaryformatter.Serialize(networkStream, kort);
}

另一方面,我接收并反序列化代码:

TcpClient tcpClient = (TcpClient)client;
tcpClient.SendTimeout = 10000;
tcpClient.ReceiveTimeout = 10000;
NetworkStream clientStream = tcpClient.GetStream();
try
{
if (clientStream.CanRead)
{
BinaryFormatter binaryformatter = new BinaryFormatter();
binaryformatter.Binder = new AllowAllAssemblyVersionsDeserializationBinder();

Kort tempkort = (Kort)binaryformatter.Deserialize(clientStream);
SetImage(tempkort);
}
}
catch (SerializationException e)
{
MessageBox.Show("Failed to deserialize. Reason: " + e.Message);
throw;
}
finally
{
clientStream.Close();
tcpClient.Close();
}

但是当我反序列化时,我得到了关于程序集丢失的错误:

"An unhandled exception of type System.Runtime.Serialization.SerializationException occurred in Server.exe Additional information: Unable to find assembly 'Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

我用这个解决了:

sealed class AllowAllAssemblyVersionsDeserializationBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
String currentAssembly = Assembly.GetExecutingAssembly().FullName;

// In this case we are always using the current assembly
typeName = "Server.Kort";
assemblyName = currentAssembly;

// Get the type using the typeName and assemblyName
Type typeToDeserialize = Type.GetType(String.Format("{0}, {1}",
typeName, assemblyName));

return typeToDeserialize;
}
}

但现在我尝试这样做时,我不断收到一条错误消息:

"Object of type Server.Kort cannot be converted to type Server.Kort+kortvalör."

而且我不知道如何修复它。

最佳答案

类(class)Kort在发送方必须包含一个名为 enum 的嵌套类型实例(可能是 kortvalör ?) .而且,自 BinaryFormatter序列化公共(public)和私有(private)字段而不是属性,嵌套类型可能对外界完全不可见,但仍会被序列化。

例如,我能够重现您的异常 "Object of type Server.Kort cannot be converted to type Server.Kort+kortvalör"将您的 Binder 与以下类一起使用:

[Serializable]
public class Kort
{
// Private enum that is invisible to the outside world.
enum kortvalör
{
Zero,
One,
Two,
Three
}

kortvalör valör = kortvalör.Three;

public int Value
{
get
{
return (int)valör;
}
set
{
// Check to make sure the incoming value is in a valid range.
var newvalör = (kortvalör)value;
if (Enum.IsDefined(typeof(kortvalör), newvalör))
valör = newvalör;
else
valör = default(kortvalör);
}
}
}

当反序列化上面的类时,您的绑定(bind)器将被调用两次,一次是使用 typeName对于 Kort -- 然后一次使用类型名称 "MyClientNamespace.Kort+kortvalör" .由于您的 Binder 忽略传入的 typeName并返回 typeof(Kort) , 这失败了。

您有几个选项可以解决这个问题:

  1. 提取你的类 Kort到共享 DLL 中并将其与发送和接收应用程序链接。然后问题就消失了。

  2. Kort 引用的所有类型创建副本在发送和接收应用程序中——包括私有(private)嵌套类型——并在你的 SerializationBinder 的更智能版本中适本地重新映射类型名称。 .文章Advanced Binary Serialization: Deserializing an Object Into a Different Type Than the One It was Serialized Into有一个如何做的例子。

  3. 考虑使用不同的序列化格式来序列化属性,而不是私有(private)字段。 BSON是一种选择。 Protobuf-net是另一个。

关于c# - 使用 binaryformatter 反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30196506/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com