代码之家  ›  专栏  ›  技术社区  ›  Mavrik

反序列化嵌套类时不需要xmlns=''

  •  8
  • Mavrik  · 技术社区  · 15 年前

    尝试序列化服务器上的类时遇到问题,请将其发送到客户端,然后反序列化在目标上。

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

    [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));
    
    4 回复  |  直到 15 年前
        1
  •  18
  •   Noctis    10 年前

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

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

    所以我不得不改变我的 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
  •  3
  •   viperguynaz    13 年前

    以下是解决问题的方法:

    [System.Xml.Serialization.XmlRootAttribute("nodeName", Namespace = "http://somenamespace", IsNullable = false)]
    
        3
  •  2
  •   Aaronaught    15 年前

    在使用 XmlSerializer . 根元素应始终如下所示:

    <MyClass 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    

    (更正:The 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
  •  0
  •   DineshNS    7 年前

    我下定决心

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