【问题标题】:Using DataContractAttribute and ISerializable使用 DataContractAttribute 和 ISerializable
【发布时间】:2011-02-23 02:27:38
【问题描述】:

我有一组已经实现 ISerializable 接口的用户定义类型,现在我想将它们托管在服务器端应用程序中,并通过使用 DataContract 属性标记它们向客户端公开这些类型。

不幸的是,当我无法使用 DataContract 属性标记同一个类时,因为它已经是 ISerializable 并且会导致运行时异常。

但同时,我无法删除旧用户定义类型中的 ISerializable 实现。

请有人帮助我如何将这些类型公开给客户端.. 通过标记 DataContract 并且不删除 ISerializable

谢谢 桑迪普

【问题讨论】:

  • 什么运行时异常?这真的不应该是一个问题......
  • 你好..我得到一个异常说一个类型不能序列化并且同时具有 DataContractAttribute..
  • 为什么要用DataContractAttribute标记这些类型?你不需要它 - 使用 ISerializable 对 WCF 来说就足够了。

标签: wcf


【解决方案1】:
【解决方案2】:

由于版本控制,一个不能识别另一个:DataContract 知道 ISerializable 是什么,但 ISerializable 不知道 DataContract 是什么

创建一个包装器怎么样?

然后发送包装器进行序列化/反序列化

  [DataContract]
class Person 
{
    public Person()
    {

    }
    public Person(string firstName, string lastName):this()
    {
        this.FirstName = firstName;
        this.LastName = LastName;
    }

    [DataMember]
    public string FirstName {get;set;}

    [DataMember]
    public string LastName { get; set; }

}

   [Serializable]
    class SerializablePersonWrapper : ISerializable 
    {
       SerializablePersonWrapper(SerializationInfo info,
                                 StreamingContext context)
        {
            string fname = info.GetString("FName");

            //did this just for answering any questions
            string lname = (string) info.GetValue("LName", typeof(string)); 

            this.PersonItem = new Person(fname, lname);

        }
       public Person PersonItem {get;set;}

       public void GetObjectData(SerializationInfo info, 
                                 StreamingContext context)
       {
           info.AddValue("FName", this.PersonItem.FirstName);
           info.AddValue("LName", this.PersonItem.LastName);
       }
    }

【讨论】:

    【解决方案3】:

    十年后,因此不是针对 OP,而是针对其他搜索此问题的人...

    根据您进行序列化的方式,您可以使用SerializationSurrogates。这允许您在调用它时选择如何处理序列化:如果您指定某个代理项,它将使用它来执行序列化。如果不指定,它将使用默认值。

    如果我们要使用他们的答案中提供的示例 Mickey Perlstein 作为起点,它可能看起来像这样:

    [DataContract]
    class Person 
    {
        public Person()
        {
    
        }
        public Person(string firstName, string lastName):this()
        {
            this.FirstName = firstName;
            this.LastName = LastName;
        }
    
        [DataMember]
        public string FirstName {get;set;}
    
        [DataMember]
        public string LastName { get; set; }
    
    }
    
    
    class PersonSerializationSurrogate : ISerializationSurrogate
    {
       public string FirstName { get; set; }
       public string LastName  { get; set; }
    
       public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
        {
            var p = (Person)obj;
            info.AddValue(nameof(FirstName), p.FirstName);
            info.AddValue(nameof(LastName),  p.LastName);
        }
    
        public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
        {
            var p = (Person)obj;
            p.FirstName = info.GetString(nameof(FirstName));
            p.LastName  = info.GetString(nameof(LastName));
    
            return p;
        }
    }
    

    当您需要控制序列化过程时,就像使用 ISerializable 一样,您可以使用这个代理来实现。主要是从链接的文章中复制:

    // This sample uses the BinaryFormatter.
    IFormatter formatter = new BinaryFormatter();
    
    // Create a MemoryStream that the object will be serialized into and deserialized from.
    using (Stream stream = new MemoryStream())
    {
        // Create a SurrogateSelector.
        var ss = new SurrogateSelector();
    
        // using the Surrogate object.
        ss.AddSurrogate(typeof(Person),
            new StreamingContext(StreamingContextStates.All),
            new PersonSerializationSurrogate());
    
        // Associate the SurrogateSelector with the BinaryFormatter.
        formatter.SurrogateSelector = ss;
    
        try
        {
            // Serialize into the memory stream.
            formatter.Serialize(stream, new Person("Jeff", "Sandepku"));
        }
        catch (SerializationException e)
        {
            Console.WriteLine($"Serialization failed: {e.Message}");
            throw;
        }
    
        // Rewind the MemoryStream.
        stream.Position = 0;
    
        try
        {
            // Deserialize from the memory stream.
            var p = (Person) formatter.Deserialize(stream);
    
            // Verify that it all worked.
            Console.WriteLine($"Name is {p.FirstName} {p.LastName}");
        }
        catch (SerializationException e)
        {
            Console.WriteLine($"Deserialization failed: {e.Message}");
            throw;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-15
      • 2021-06-08
      • 1970-01-01
      • 1970-01-01
      • 2011-02-06
      • 1970-01-01
      • 1970-01-01
      • 2011-02-11
      相关资源
      最近更新 更多