2011-04-03 65 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

相關問題