I have the following classes:
namespace XmlSerializerTest
{
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
[Serializable]
[XmlRoot( Namespace = "My:NS" )]
[XmlType( Namespace = "My:NS" )]
[XmlInclude( typeof( Command ) )]
[XmlInclude( typeof( ImSession ) )]
public class CommandBase
{
[XmlAttribute]
public string Version { get; set; }
}
[Serializable]
[XmlType( Namespace = "My:NS" )]
[XmlInclude( typeof( ImSession[ ] ) )]
public class Command : CommandBase
{
[XmlArray]
[XmlArrayItem( typeof( ImSession ) )]
public object[ ] Content { get; set; }
}
[Serializable]
[XmlType( Namespace = "My:NS" )]
public class ImSession
{
[XmlElement]
public string ClientId { get; set; }
[XmlElement]
public DateTime StartTime { get; set; }
[XmlArray]
public List<Matrix.Xmpp.Client.Message> Messages { get; set; }
}
}
I use the following code to serialize a Command object:
XmlSerializer ser = new XmlSerializer( typeof( CommandBase ) );
Command c = new Command
{
Version = "TEST",
Content = new object[ ]
{
new ImSession
{
ClientId = "Client A",
StartTime = DateTime.Today,
Messages = {
new Matrix.Xmpp.Client.Message( "a@b.com/c" ) { Body = "TEST BODY A" },
new Matrix.Xmpp.Client.Message( "a@b.com/c" ) { Body = "TEST BODY B" }
}
},
new ImSession
{
ClientId = "Client B",
StartTime = DateTime.Now,
Messages =
{
new Matrix.Xmpp.Client.Message( "c@b.com/a" ) { Body = "TEST BODY C" },
new Matrix.Xmpp.Client.Message( "c@b.com/a" ) { Body = "TEST BODY D" }
}
}
}
};
ser.Serialize( Console.Out, c );
This results in the following XML, which the same serializer can't properly deserialize:
<?xml version="1.0" encoding="utf-8"?>
<CommandBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="Command" Version="TEST" xmlns="My:NS">
<Content>
<ImSession>
<ClientId>Client A</ClientId>
<StartTime>2015-08-11T00:00:00-04:00</StartTime>
<Messages>
<Message>
<message to="a@b.com/c" xmlns="jabber:client">
<body>TEST BODY A</body>
</message>
</Message>
<Message>
<message to="a@b.com/c" xmlns="jabber:client">
<body>TEST BODY B</body>
</message>
</Message>
</Messages>
</ImSession>
<ImSession>
<ClientId>Client B</ClientId>
<StartTime>2015-08-11T21:55:18.4624832-04:00</StartTime>
<Messages>
<Message>
<message to="c@b.com/a" xmlns="jabber:client">
<body>TEST BODY C</body>
</message>
</Message>
<Message>
<message to="c@b.com/a" xmlns="jabber:client">
<body>TEST BODY D</body>
</message>
</Message>
</Messages>
</ImSession>
</Content>
</CommandBase>
What happens when deserializing is that the Messages collection is null. I believe the problem to be the extra "Message" wrapper element around the actual "message" elements. If I change it to be an array of objects, it is no longer null, but contains the correct number of objects, but including that extra wrapper.
How can I get rid of that extra Message element around the message elements?
Note I am using the Matrix XMPP library (available on NuGet) for that Message class.
The XML I want to achieve is:
<?xml version="1.0" encoding="utf-8"?>
<CommandBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="Command" Version="TEST" xmlns="My:NS">
<Content>
<ImSession>
<ClientId>Client A</ClientId>
<StartTime>2015-08-11T00:00:00-04:00</StartTime>
<Messages>
<message to="a@b.com/c" xmlns="jabber:client">
<body>TEST BODY A</body>
</message>
<message to="a@b.com/c" xmlns="jabber:client">
<body>TEST BODY B</body>
</message>
</Messages>
</ImSession>
<ImSession>
<ClientId>Client B</ClientId>
<StartTime>2015-08-11T21:55:18.4624832-04:00</StartTime>
<Messages>
<message to="c@b.com/a" xmlns="jabber:client">
<body>TEST BODY C</body>
</message>
<message to="c@b.com/a" xmlns="jabber:client">
<body>TEST BODY D</body>
</message>
</Messages>
</ImSession>
</Content>
</CommandBase>
Here is deserialization code for the same object:
StringBuilder sb = new StringBuilder( );
ser.Serialize( new StringWriter( sb ), c );
object d = ser.Deserialize( new StringReader( sb.ToString( ) ) );
Inspecting d
in the debugger shows that it is, in fact, a Command object, with ImSessions in it, and the Messages array of each has objects in it, which it claims are Matrix.Xmpp.Client.Message, but which have all properties null (matching the xml), except for their private collection of child nodes, which have the actual Message objects in them, with all properties as expected.