2011-04-03 54 views
4

在开发一个测试用例来理解序列化的过程中,我遇到了看起来像是直截了当的问题,但无法弄清楚。我希望能够将多个对象添加到列表<>,然后序列化该列表(在这种情况下,我正在使用DataContractJsonSerializer)。创建对象(node1和node2)后,我想将它们添加到列表<>(cn)并序列化它。但是,当添加node1和node2时,我得到一个无效的参数错误(“无法从'JSON_test.Aspirate'转换为'JSON_test.CompositeNode')。我相信这是让数组知道基类型的问题,但我不知道“知道该怎么做,或者如果实际上这是问题(还是这一切很新)。DataContract包含对象的List <>的序列化

谢谢。

namespace JSON_test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Aspirate node1 = new Aspirate(25,40); 
      Dispense node2 = new Dispense(32,50); 
      ObjectToSerialize cn = new ObjectToSerialize(); 
      cn.CompositeNode.Add (node1); 
      cn.CompositeNode.Add (node2); 

      MemoryStream stream1 = new MemoryStream(); 
      DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ObjectToSerialize)); 
      ser.WriteObject(stream1, cn.CompositeNode); 
      stream1.Position = 0; 
      StreamReader sr = new StreamReader(stream1); 
      Console.WriteLine(sr.ReadToEnd()); 
      Console.ReadLine(); 
     } 
    } 

    [DataContract] 
    public class ObjectToSerialize 
    { 
     private List<CompositeNode> compNode; 
     [DataMember] 
     public List<CompositeNode> CompositeNode 
     { 
      get {return this.CompositeNode;} 
      set { this.compNode = value; } 
     } 

     public ObjectToSerialize() 
     { 
     } 
    } 

    [DataContract] 
    public class CompositeNode 
    { 

    } 

    [DataContract] 
    public class Aspirate 
    { 
     [DataMember] 
     public string NodeName = "Aspirate"; 
     [DataMember] 
     public double ZTravelHt; 
     [DataMember] 
     public double IndexHt; 

     public Aspirate(double ZTravelHt, double IndexHt) 
     { 
      this.ZTravelHt = ZTravelHt; 
      this.IndexHt = IndexHt; 
     } 
    } 

    [DataContract] 
    public class Dispense 
    { 
     [DataMember] 
     public string NodeName = "Dispense"; 
     [DataMember] 
     public double ZTravelHt; 
     [DataMember] 
     public double IndexHt; 

     public Dispense(double ZTravelHt, double IndexHt) 
     { 
      this.ZTravelHt = ZTravelHt; 
      this.IndexHt = IndexHt;    
     } 
    } 
} 

UPDATE

namespace JSON_test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Aspirate node1 = new Aspirate(25,40); 
      Dispense node2 = new Dispense(32,50); 
      ObjectToSerialize cn = new ObjectToSerialize(); 
      cn.CompositeNode.Add (node1); 
      cn.CompositeNode.Add (node2); 

      MemoryStream stream1 = new MemoryStream(); 
      DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ObjectToSerialize), 
       new Type[] {typeof (Aspirate), typeof (Dispense)}); 
      ser.WriteObject(stream1, cn.CompositeNode); 
      stream1.Position = 0; 
      StreamReader sr = new StreamReader(stream1); 
      Console.WriteLine(sr.ReadToEnd()); 
      Console.ReadLine(); 
     } 
    } 

    [DataContract] 
    [KnownType(typeof(Aspirate))] 
    [KnownType(typeof(Dispense))] 
    public class ObjectToSerialize 
    { 
     private List<CompositeNode> compNode = new List<CompositeNode>(); 

     [DataMember] 
     public List<CompositeNode> CompositeNode 
     { 
      get {return this.compNode;} 
      set { this.compNode = value; } 
     } 

     public ObjectToSerialize() 
     { 

     } 
    } 

    [DataContract] 
    [KnownType(typeof(Aspirate))] 
    [KnownType(typeof(Dispense))] 
    public class CompositeNode 
    { 

    } 

    [DataContract] 
    public class Aspirate : CompositeNode 
    { 
     [DataMember] 
     public string NodeName = "Aspirate"; 
     [DataMember] 
     public double ZTravelHt; 
     [DataMember] 
     public double IndexHt; 

     public Aspirate(double ZTravelHt, double IndexHt) 
     { 
      this.ZTravelHt = ZTravelHt; 
      this.IndexHt = IndexHt; 
     } 
    } 

    [DataContract] 
    public class Dispense : CompositeNode 
    { 
     [DataMember] 
     public string NodeName = "Dispense"; 
     [DataMember] 
     public double ZTravelHt; 
     [DataMember] 
     public double IndexHt; 

     public Dispense(double ZTravelHt, double IndexHt) 
     { 
      this.ZTravelHt = ZTravelHt; 
      this.IndexHt = IndexHt;    
     } 
    } 
} 

回答

6

你可以将KnownTypeAttribute添加到ObjectToSerialize让串行知道会发生哪些类型:

[DataContract] 
[KnownType(typeof(Aspirate))] 
[KnownType(typeof(Dispense))] 
public class ObjectToSerialize 
{ 
    .... 
} 

据我所知,类AspirateDispenseCompositeNode衍生?这从您的代码示例中不清楚。

你在你的代码中的错误的方式:

get {return this.CompositeNode;}  

应该是:

get {return this.compNode;}  

更新:在resoponse在评论你的问题:你并初始化的收集ObjectToSerialize的构造函数中:

public ObjectToSerialize() 
{ 
    this.compNode = new List<CompositeNode>(); 
} 

更新2:线,这是错误的:

ser.WriteObject(stream1, cn.CompositeNode); 

这应该是:

ser.WriteObject(stream1, cn); 

顺便说一句,你可以这样写:

DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ObjectToSerialize)); 

你已经通过使用属性定义已知类型。将已知类型添加到构造函数是多余的。

+0

谢谢。这让我朝着正确的方向前进。我添加了KnownTypes,纠正了错误,并将“:CompositeNode”添加到Aspirate和Dispense类中。它现在编译,但是当节点被添加到列表时会给出一个NullReferenceException。这告诉我CompositeNode类需要一些东西,但我的经验不足。有什么建议么? – user269689 2011-04-03 22:01:16

+0

您需要在classObjectToSerialize中初始化compNode – 2011-04-03 22:07:26

+0

再次感谢您的帮助。我将“private List compNode”更改为“private List compNode = new List ();”。该列表现在填充了两个节点,但我得到一个SerializationException - “ArrayOfCompositeNode:http://schemas.datacontract.org/2004/07/JSON_test”不是预期的“ – user269689 2011-04-03 22:34:55

相关问题