【问题标题】:How can I deserialize an object if I don't know the right type?如果我不知道正确的类型,如何反序列化对象?
【发布时间】:2012-02-29 01:19:13
【问题描述】:

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

我有三个项目:

  • 客户
  • 服务器
  • Common - 这里我放了公共类和网络抽象层

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

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&lt;FilesInfo&gt;(filesInfo) 的数据包,然后对其进行序列化并将其发送到客户端\服务器。

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

【问题讨论】:

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


    【解决方案1】:

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

    【讨论】:

      【解决方案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】:

        chrfin 和 haiyyu 都有相同的好主意。下面是使用 Packet Base 类来保存构造类型数据的小改动。您序列化一个 Packet 并反序列化为一个 Packet。那么使用就很简单了。仍然如前所述的诀窍是使 Type 易于访问。

        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();
            }
        }
        

        【讨论】:

          【解决方案4】:

          如果您使用 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
              }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-11-22
            • 2013-10-16
            • 2011-07-03
            • 1970-01-01
            • 2010-12-20
            • 2012-11-21
            相关资源
            最近更新 更多