I had the students to go and research out how to use the build in XML serialisation functions in C#, and we were going to use them to to covert all our message classes into XML for sending over the network.
I went to class, we all started coding...
public class SomeData { public int a; public float b; public string c; } // create new object and populate myData data SomeData myData = new SomeData(); myData.a = 5; myData.b = 8.8f; myData.c = "MeString"; // Serialization - convert to XML XmlSerializer sendSerializer = new XmlSerializer(typeof(SomeData)); StreamWriter myWriter = new StreamWriter(@"savingXML.xml"); sendSerializer.Serialize(myWriter, myData); myWriter.Close(); // Deserialization - convert back to a structure XmlSerializer revSerializer = new XmlSerializer(typeof(SomeData)); FileStream myFileStream = new FileStream(@"savingXML.xml", FileMode.Open); myData = (SomeData)revSerializer.Deserialize(myFileStream);
It all coming together so well until...
<Insert dramatic music here>
I went on with the second part which was to have multiple objects types being serialised.
This is when it all fell apart
The problem
Look back the previous code, do you see when the XmlSerializer is being created it needs a type. You put in the wrong type and it just throws an exception. I tried using typeof(Object), I tried base classes, and all other things. Eventually I found a site which explained it indirectly.
How To Solve the issue
The XmlSerializer will accept a type and an array of types, and it accept any of the types specified.
So this works:
public class SomeDataA{...} public class SomeDataB{...} public class SomeDataC{...} // create new object and populate myData data SomeDataA myDataA = new SomeDataA(); SomeDataB myDataB = new SomeDataB(); SomeDataC myDataC = new SomeDataC(); // Serialization - convert to XML XmlSerializer sendSerializer = new XmlSerializer(typeof(SomeDataA),new Type[]{typeof(SomeDataB),typeof(SomeDataC)}); StreamWriter myWriter = new StreamWriter(@"savingXML.xml"); sendSerializer.Serialize(myWriter, myDataA); sendSerializer.Serialize(myWriter, myDataB); sendSerializer.Serialize(myWriter, myDataC); myWriter.Close(); // and the same for Deserialization
It also means that I can now easily have a whole hierarchy provided I know all the classes.
public class Base{...} public class Derived1: Base{...} public class Derived2: Base{...} // Deserialization - convert back to a structure XmlSerializer revSerializer = new XmlSerializer(typeof(Base),new Type[]{typeof(Derived1),typeof(Derived2)}); FileStream myFileStream = new FileStream(@"savingXML.xml", FileMode.Open); Base b = (Base)revSerializer.Deserialize(myFileStream); if (b is Derived1) { Derived1 d1=(Derived1)b; // do stuff with d1 } else if (b is Derived2) { Derived2 d2=(Derived2)b; // do stuff with d2 }
Conclusion
In order to use the C# XmlSerializer, you need to have specify all possible classes which could be used. This is a bit of a bind, but know I know about the issue, I won't fall foul of it again
I'm sure the Java XmlSerializer doesn't have this funny issue. But its not the total show stopper, just an annoyance, and it messed up my class yesterday.
So next week, I need to be a bit better prepared..
Happy Coding:
Mark
No comments:
Post a Comment