如果我不知道正确的类型,如何反序列化对象?

时间:2012-02-07 15:43:26

标签: c# .net serialization client-server deserialization

我想在客户端和服务器之间发送命令和数据。

我有三个项目:

  • 客户端
  • 服务器
  • 常见 - 这里我放了常用类和网络抽象层

我正在使用以下数据结构进行客户端和服务器之间的通信

public class Packet<T>
{
        public string Name { get; set; }
        public string From { get; set; }
        public string To { get; set; }
        public PacketType PacketType { get; set; }
        public T Container { get; set; }

        public Packet()
        {
        }

        public Packet(string name, PacketType packetType, T container)
        {
            Name = name;
            PacketType = packetType;
            Container = container;
        }
    }

    public enum PacketType
    {
        Command,
        Data
    }

如果我需要发送有关文件的信息,我只需创建一个具有必要结构CreatePacket<FilesInfo>(filesInfo)的数据包,然后将其序列化并发送到客户端\服务器。

但是如何在接收端反序列化数据呢?我不知道数据包的对象类型是什么。有没有其他方式或库或东西来解决我的问题?此外,我不想使用WCF,因为我的应用程序应该在安装了.NET 2.0的计算机上运行。

4 个答案:

答案 0 :(得分:3)

chrfin和haiyyu都有同样的想法。下面是使用Packet Base类来保存构造类型数据的一个小麻烦。您序列化数据包&lt; T>并反序列化为数据包。使用非常简单。仍然提到的技巧是使类型易于访问。

class Program
{
    static void Main(string[] args)
    {
        var pack = new Packet<int>() { Payload = 13 };
        var serializedData = pack.Serialize();
        var deserializedData = Packet.Deserialize(serializedData);
        Console.WriteLine("The payload type is:" + deserializedData.PayloadType.Name);
        Console.WriteLine("the payload is: " + deserializedData.Payload);
        Console.ReadLine();
    }
}



[Serializable]
public class Packet
{
    public Type PayloadType { get; protected set; }
    public object Payload { get; protected set; }
    public static Packet Deserialize(byte[] bytes)
    {
        return (Packet)(new BinaryFormatter()).Deserialize(new MemoryStream(bytes));
    }
}

[Serializable]
class Packet<T> : Packet
{
    public Packet()
    {
        PayloadType = typeof(T);
    }
    public new T Payload 
    {
        get { return (T)base.Payload; } 
        set { base.Payload = value; } 
    }

    public override string ToString()
    {
        return "[Packet]" + Payload.ToString();
    }

    public byte[] Serialize()
    {
        MemoryStream m = new MemoryStream();
        (new BinaryFormatter()).Serialize(m, this);
        return m.ToArray();
    }
}

答案 1 :(得分:2)

服务器和客户端应用程序都必须使用相同的类型。然后,发送方可以将数据类型告知接收方为字符串,接收方将能够使用Type.GetType()获取类型。

答案 2 :(得分:2)

您可以将paket封装在也包含类型的容器中:

public class Container
{
    public Type PacketType { get; set; }
    public byte[] Packet { get; set; }
}

然后

Container c = (Container)cSerializer.Deserialize(/*Your Received Packet*/);
Packet<c.PacketType> paket = 
    (Packet<c.PacketType>)pSerializer.Deserialize(new MemoryStream(c.Packet));

或者您可以要求T始终扩展基类,然后在接收方使用它:

Packet<BaseClass> paket = 
    (Packet<BaseClass>)pSerializer.Deserialize(new MemoryStream(/*Data*/));

答案 3 :(得分:0)

如果您正在使用XML序列化,这似乎运作良好....

private string GetClassNameFromXMLSerializedString(string xml)
    {
        xml = xml.Substring(xml.IndexOf(">\r\n<") + 3, 50);//get second XML element
        return xml.Substring(1, xml.IndexOf(' ') - 1);//get class name
    }