J
jpalmer
Hi,
I’m setting up a .NET 2.0 c# WebService. One of the web methods requires a
complex parameter type which contains circular references, so by default
XmlSerializer can not serialise and deserialise the .NET object. I.e The
circular type looks something like this:
1 public class A
2 {
3 public A()
4 {
5
6 }
7
8 public A(int id)
9 {
10 this.Id = id;
11 }
12 public int Id;
13 public B B;
14 }
15
16 public class B
17 {
18 public B()
19 {
20
21 }
22 public B(int id)
23 {
24 this.Id = id;
25 }
26 public int Id;
27 public A A;
28 }
29
Now I can easily implement IXmlSerializable.WriteXML to write the XML to a
form the deals with the circular reference. i.e.
1 using System;
2 using System.IO;
3 using System.Xml;
4 using System.Xml.Serialization;
5
6 public class A : IXmlSerializable
7 {
8 public A()
9 {
10
11 }
12 public A(int id)
13 {
14 this.Id = id;
15 }
16 public int Id;
17 public B B;
18 public void WriteXml(XmlWriter w)
19 {
20 w.WriteStartElement("A");
21 w.WriteElementString("Id", Id.ToString());
22 B.WriteXml(w);
23 w.WriteEndElement();
24 }
25 public void ReadXml(XmlReader r)
26 {
27 throw new NotImplementedException();
28 }
29
30 public System.Xml.Schema.XmlSchema GetSchema()
31 {
32 throw new NotImplementedException();
33 }
34 }
35
36 public class B : IXmlSerializable
37 {
38 public B()
39 {
40
41 }
42
43 public B(int id)
44 {
45 this.Id = id;
46 }
47
48 public int Id;
49 public A A;
50 public void WriteXml(XmlWriter w)
51 {
52 w.WriteStartElement("B");
53 w.WriteElementString("Id", Id.ToString());
54 w.WriteStartElement("A");
55 w.WriteAttributeString("RefID", A.Id.ToString());
56 w.WriteEndElement();
57 w.WriteEndElement();
58 }
59 public void ReadXml(XmlReader r)
60 {
61 throw new NotImplementedException();
62 }
63 public System.Xml.Schema.XmlSchema GetSchema()
64 {
65 throw new NotImplementedException();
66 }
67 }
This produces output like this:
<?xml version="1.0" encoding="utf-8" ?>
<A xmlns="http://something.com/">
<A>
<Id>1</Id>
<B>
<Id>2</Id>
<A RefID="1" />
</B>
</A>
</A>
But how do I deserialise the XML stream and set the correct object
reference, making sure that it is done once the object tree is fully read?
With the System.Runtime.Serialization framework I could do with by fixing
the object references after the object tree was read by implementing the
IDeserializationCallback.OnDeserialization(Object sender) method. But there
does not seem to be anything similar for the System.Xml.Serialization
framework.
Any help would be greatly appreciated.
Cheers,
Jeremy
I’m setting up a .NET 2.0 c# WebService. One of the web methods requires a
complex parameter type which contains circular references, so by default
XmlSerializer can not serialise and deserialise the .NET object. I.e The
circular type looks something like this:
1 public class A
2 {
3 public A()
4 {
5
6 }
7
8 public A(int id)
9 {
10 this.Id = id;
11 }
12 public int Id;
13 public B B;
14 }
15
16 public class B
17 {
18 public B()
19 {
20
21 }
22 public B(int id)
23 {
24 this.Id = id;
25 }
26 public int Id;
27 public A A;
28 }
29
Now I can easily implement IXmlSerializable.WriteXML to write the XML to a
form the deals with the circular reference. i.e.
1 using System;
2 using System.IO;
3 using System.Xml;
4 using System.Xml.Serialization;
5
6 public class A : IXmlSerializable
7 {
8 public A()
9 {
10
11 }
12 public A(int id)
13 {
14 this.Id = id;
15 }
16 public int Id;
17 public B B;
18 public void WriteXml(XmlWriter w)
19 {
20 w.WriteStartElement("A");
21 w.WriteElementString("Id", Id.ToString());
22 B.WriteXml(w);
23 w.WriteEndElement();
24 }
25 public void ReadXml(XmlReader r)
26 {
27 throw new NotImplementedException();
28 }
29
30 public System.Xml.Schema.XmlSchema GetSchema()
31 {
32 throw new NotImplementedException();
33 }
34 }
35
36 public class B : IXmlSerializable
37 {
38 public B()
39 {
40
41 }
42
43 public B(int id)
44 {
45 this.Id = id;
46 }
47
48 public int Id;
49 public A A;
50 public void WriteXml(XmlWriter w)
51 {
52 w.WriteStartElement("B");
53 w.WriteElementString("Id", Id.ToString());
54 w.WriteStartElement("A");
55 w.WriteAttributeString("RefID", A.Id.ToString());
56 w.WriteEndElement();
57 w.WriteEndElement();
58 }
59 public void ReadXml(XmlReader r)
60 {
61 throw new NotImplementedException();
62 }
63 public System.Xml.Schema.XmlSchema GetSchema()
64 {
65 throw new NotImplementedException();
66 }
67 }
This produces output like this:
<?xml version="1.0" encoding="utf-8" ?>
<A xmlns="http://something.com/">
<A>
<Id>1</Id>
<B>
<Id>2</Id>
<A RefID="1" />
</B>
</A>
</A>
But how do I deserialise the XML stream and set the correct object
reference, making sure that it is done once the object tree is fully read?
With the System.Runtime.Serialization framework I could do with by fixing
the object references after the object tree was read by implementing the
IDeserializationCallback.OnDeserialization(Object sender) method. But there
does not seem to be anything similar for the System.Xml.Serialization
framework.
Any help would be greatly appreciated.
Cheers,
Jeremy