尝试在服务器上序列化类,将其发送到客户端并在目标上反序列化时遇到问题。
在服务器上,我有以下两个类:
[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; }
}
和
[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; }
}
(缺少的类型都是枚举)。
这将在序列化上生成以下XML:
<?xml version="1.0" encoding="utf-16"?>
<StatusUpdate>
<Players>
<Player Color="Cyan" X="67" Y="32" />
</Players>
<Command>StartGame</Command>
</StatusUpdate>
在客户端,我试图将其反序列化为以下类:
[XmlRoot("StatusUpdate")]
public class StatusUpdate
{
public StatusUpdate()
{
}
[XmlArray("Players")]
[XmlArrayItem("Player")]
public PlayerInfo[] Players { get; set; }
[XmlElement("Command")]
public Command Update { get; set; }
}
和
[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; }
}
但是,反序列化器抛出异常:
There is an error in XML document (2, 2).
<StatusUpdate xmlns=''> was not expected.
我错过了什么或做错了什么?
编辑:
根据要求,我还添加了用于序列化和反序列化的代码:
服务器:
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());
}
客户端:
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;
}
使用
调用反序列化StatusUpdate update = (StatusUpdate) Util.DeserializeXml(xmlData, typeof (StatusUpdate));
答案 0 :(得分:18)
经过大量测试后,我终于发现了一个错误。它不是编码问题,也不是其他代码中的问题,也不是缺少的命名空间。
缺少的部分是反序列化时数组中对象类型的注释。
所以我必须将我的StatusUpdate
课改为
[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; }
}
和序列化开始完美运作。
我希望能帮到别人。
答案 1 :(得分:3)
这是为我解决的问题:
[System.Xml.Serialization.XmlRootAttribute("nodeName", Namespace = "http://somenamespace", IsNullable = false)]
答案 2 :(得分:2)
使用XmlSerializer
时,实际上非常不寻常。根元素应始终如下所示:
<MyClass
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
(更正:XmlSerializer
确实在反序列化时似乎无法使用它们,但它总是在序列化时添加它们,所以如果它们丢失则会出现问题。)
第二次修改:
我强烈怀疑您的问题与编码有关。我不知道为什么你必须如此混乱序列化,不能只使用默认的UTF-8编码,但无论如何,以下代码都可以正常工作:
MyClass m = new MyClass() { X = 4, Y = 8 };
byte[] data = SerializeObject(m);
string xml = Encoding.Unicode.GetString(data);
Console.WriteLine(xml);
m = (MyClass)DeserializeXml(xml, typeof(MyClass));
因此,如果某些内容失败了,那么在将字节数组转换为客户端的XML字符串时,很可能会出错。这是你尚未发布的唯一代码。
答案 3 :(得分:0)
我通过以下
得到了解决 XmlSerializer serializer = new XmlSerializer(typeof(CustomerPhoto), "http://example.com/webservices/");
CustomerPhoto returnObject = (CustomerPhoto)serializer.Deserialize(xmlStream);