I have a problem when attempting to serialize class on a server, send it to the client and deserialize is on the destination.
On the server I have the following two classes:
[XmlRoot("StatusUpdate")]
public class GameStatusUpdate
{
public GameStatusUpdate()
{}
public GameStatusUpdate(Player[] players, Command command)
{
this.Players = players;
this.Update = command;
}
[XmlArray("Players")]
public Player[] Players { get; set; }
[XmlElement("Command")]
public Command Update { get; set; }
}
and
[XmlRoot("Player")]
public class Player
{
public Player()
{}
public Player(PlayerColors color)
{
Color = color;
...
}
[XmlAttribute("Color")]
public PlayerColors Color { get; set; }
[XmlAttribute("X")]
public int X { get; set; }
[XmlAttribute("Y")]
public int Y { get; set; }
}
(The missing types are all enums).
This generates the following XML on serialization:
<?xml version="1.0" encoding="utf-16"?>
<StatusUpdate>
<Players>
<Player Color="Cyan" X="67" Y="32" />
</Players>
<Command>StartGame</Command>
</StatusUpdate>
On the client side, I'm attempting to deserialize that into following classes:
[XmlRoot("StatusUpdate")]
public class StatusUpdate
{
public StatusUpdate()
{
}
[XmlArray("Players")]
[XmlArrayItem("Player")]
public PlayerInfo[] Players { get; set; }
[XmlElement("Command")]
public Command Update { get; set; }
}
and
[XmlRoot("Player")]
public class PlayerInfo
{
public PlayerInfo()
{
}
[XmlAttribute("X")]
public int X { get; set; }
[XmlAttribute("Y")]
public int Y { get; set; }
[XmlAttribute("Color")]
public PlayerColor Color { get; set; }
}
However, the deserializer throws an exception:
There is an error in XML document (2, 2).
<StatusUpdate xmlns=''> was not expected.
What am I missing or doing wrong?
EDIT:
On request I'm also adding code used to serialize and deserialize:
Server:
public static byte[] SerializeObject(Object obj)
{
XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
StringWriter writer = new StringWriter();
// Clear pre-defined namespaces
XmlSerializerNamespaces xsn = new XmlSerializerNamespaces();
xsn.Add("", "");
xmlSerializer.Serialize(writer, obj, xsn);
writer.Flush();
// Send as little-endian UTF-16 string because the Serializer denotes XML as
// utf-18 which cannot be easly changed
UnicodeEncoding encoder = new UnicodeEncoding(false, false);
return encoder.GetBytes(writer.ToString());
}
Client:
public static object DeserializeXml(string xmlData, Type type)
{
XmlSerializer xmlSerializer = new XmlSerializer(type);
StringReader reader = new StringReader(xmlData);
object obj = xmlSerializer.Deserialize(reader);
return obj;
}
Deserialization is invoked with
StatusUpdate update = (StatusUpdate) Util.DeserializeXml(xmlData, typeof (StatusUpdate));
After alot of testing I have finally found an error. It was not an encoding problem, neither was the problem in the other code nor it was the missing namespace.
The missing part was the annotation for type of objects in the array when deserializing.
So I had to change my StatusUpdate
class to
[XmlRoot("StatusUpdate")]
public class StatusUpdate
{
public StatusUpdate()
{
}
[XmlArray("Players"), XmlArrayItem(ElementName = "Player", Type = typeof(PlayerInfo))]
public PlayerInfo[] Players { get; set; }
[XmlElement("Command")]
public ServerCommand Update { get; set; }
}
and serialization started working perfectly.
I hope that helps someone else.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With