【问题标题】:xmlns='' was not expected when deserializing nested classes反序列化嵌套类时不需要 xmlns=''
【发布时间】:2010-05-09 13:33:11
【问题描述】:

我在尝试在服务器上序列化类时遇到问题,将其发送到客户端并且反序列化在目的地。

在服务器上我有以下两个类:

[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));

【问题讨论】:

  • 您缺少的第一件事是没有向我们展示您用于反序列化的代码。
  • 这还不完整。当字符串xmlData 在另一端被序列化为字节时,它从何而来?如果这实际上是一个编码问题,我不会感到惊讶。为什么你的评论没有提到“utf-18”?
  • 就我而言,这是因为XmlSerializer 的错误声明。所以也要检查一下。

标签: c# .net xml xml-serialization


【解决方案1】:

经过大量测试,我终于发现了一个错误。这不是编码问题,也不是其他代码中的问题,也不是缺少命名空间。

缺少的部分是反序列化时数组中对象类型的注释。

所以我不得不将我的 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; }
}

序列化开始完美运行。

我希望这对其他人有所帮助。

【讨论】:

    【解决方案2】:

    这是为我解决的问题:

    [System.Xml.Serialization.XmlRootAttribute("nodeName", Namespace = "http://somenamespace", IsNullable = false)]
    

    【讨论】:

      【解决方案3】:

      在使用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 字符串的过程中出错。这是您仍然没有发布的唯一代码。

      【讨论】:

        【解决方案4】:

        我解决了以下问题

                    XmlSerializer serializer = new XmlSerializer(typeof(CustomerPhoto), "http://example.com/webservices/");
                    CustomerPhoto returnObject = (CustomerPhoto)serializer.Deserialize(xmlStream);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-12-30
          • 1970-01-01
          • 1970-01-01
          • 2020-06-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多