【问题标题】:.NET: How to binary serialize an object with attribute [DataContract]?.NET:如何对具有属性 [DataContract] 的对象进行二进制序列化?
【发布时间】:2010-03-04 23:01:33
【问题描述】:

标记为 [DataContract] 的类不能同时是 ISerializable。好的,那么如何将这种类型的对象序列化为二进制流呢?

private byte[] GetRoomAsBinary(Room room)
        {
            MemoryStream stream = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(stream, room);
            return stream.ToArray();
        }

如果 Room 没有 ISerializable,我无法使其工作。 如何以其他方式从对象中获取字节数组?

【问题讨论】:

    标签: .net wcf


    【解决方案1】:

    使用二进制格式化程序进行序列化和反序列化的代码:

    public static class BinarySerializer
    {
        public static byte[] Serialize<T>(T obj)
        {
            var serializer = new DataContractSerializer(typeof(T));
            var stream = new MemoryStream();
            using (var writer = 
                XmlDictionaryWriter.CreateBinaryWriter(stream))
            {
                serializer.WriteObject(writer, obj);
            }
            return stream.ToArray();
        }
    
        public static T Deserialize<T>(byte[] data)
        {
            var serializer = new DataContractSerializer(typeof(T));
            using (var stream = new MemoryStream(data))
            using (var reader = 
                XmlDictionaryReader.CreateBinaryReader(
                    stream, XmlDictionaryReaderQuotas.Max))
            {
                return (T)serializer.ReadObject(reader);
            }
        }
    }
    

    用法:

    public void TestBinarySerialization()
    {
        // Create the person object.
        Person person = new Person { Name = "John", Age = 32 };
    
        // Serialize and deserialize the person object.
        byte[] data = BinarySerializer.Serialize<Person>(person);
        Person newPerson = BinarySerializer.Deserialize<Person>(data);
    
        // Assert the properties in the new person object.
        Debug.Assert(newPerson.Age == 32);
        Debug.Assert(newPerson.Name == "John");
    }
    

    【讨论】:

      【解决方案2】:

      解决办法是使用DataContractSerializer来序列化对象。

      【讨论】:

      • DataContractSerializer 生成并读取 XML。而且 XML 不是二进制的。
      【解决方案3】:

      这就是二进制序列化的原理:只有 [Serializable] 类可以被序列化(尽管我可能已经读到这个限制最近被取消了)。 如果您想控制序列化过程,请实现 ISerializable。

      如果 Room 类有不可序列化的成员,你也需要 ISerializable。

      Room 的成员是什么?

      【讨论】:

      • 正如我所写:您不能同时拥有可序列化和数据契约的类。这会在运行时引发异常
      • 是否可以拥有 Room 类的副本,比如 RoomProxy 具有相同的成员,可序列化但不参与 DataContract ?为了避免重复,可以有一个未标记为 [DataContract] 的 Room 子类;它可以通过实现 ISerializable 来序列化。
      猜你喜欢
      • 1970-01-01
      • 2013-02-12
      • 1970-01-01
      • 1970-01-01
      • 2010-12-17
      • 2011-10-18
      • 1970-01-01
      • 2012-07-21
      • 2013-12-23
      相关资源
      最近更新 更多