DataContract Serializing a List of <> Containing Objects

When developing a test case to understand serialization, I came across what looks like a problem with a disconnected call, but I can not understand. I want to be able to add multiple objects to the <> list, and then serialize this list (in this case, I use DataContractJsonSerializer). After creating the objects (node1 and node2) I want to add them to List <> (cn) and serialize. However, I get an incorrect argument error when adding node1 and node2 ("cannot be converted from" JSON_test.Aspirate "to" JSON_test.CompositeNode "). I believe this is a question letting the array know about the base types, but I don't know I don’t know how to do this, or if this is actually a problem (still very new to all of this).

Thanks.

 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; } } } 
+4
source share
1 answer

You can add KnownTypeAttribute to ObjectToSerialize so that the serializer knows what types to expect:

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

I understand that the Aspirate and Dispense classes Aspirate derived from CompositeNode ? This is not clear from your sample code.

You have an error in the code:

 get {return this.CompositeNode;} 

it should be:

 get {return this.compNode;} 

Update: in response to your question in the comments: you should initialize the collection inside the ObjectToSerialize constructor:

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

Update 2: Wrong line:

 ser.WriteObject(stream1, cn.CompositeNode); 

It should be:

 ser.WriteObject(stream1, cn); 

By the way, you can simply write this:

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

You have already defined known types using attributes. Adding known types to the constructor is redundant.

+6
source

Source: https://habr.com/ru/post/1346475/


All Articles