2010-05-09 10 views
8

Tengo un problema al intentar serializar la clase en un servidor, enviarla al cliente y deserializar en el destino.xmlns = '' no se esperaba al deserializar las clases anidadas

En el servidor que tengo las dos clases siguientes:

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

y

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

(Los tipos que faltan son todas las enumeraciones).

Esto genera el siguiente código XML en la serialización:

<?xml version="1.0" encoding="utf-16"?> 
<StatusUpdate> 
    <Players> 
    <Player Color="Cyan" X="67" Y="32" /> 
    </Players> 
    <Command>StartGame</Command> 
</StatusUpdate> 

En el lado del cliente, estoy tratando de deserializar que en las clases siguientes:

[XmlRoot("StatusUpdate")] 
public class StatusUpdate 
{ 
    public StatusUpdate() 
    { 

    } 

    [XmlArray("Players")] 
    [XmlArrayItem("Player")] 
    public PlayerInfo[] Players { get; set; } 

    [XmlElement("Command")] 
    public Command Update { get; set; } 
} 

y

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

Sin embargo, el deserializador arroja una excepción:

There is an error in XML document (2, 2). 
<StatusUpdate xmlns=''> was not expected. 

¿Qué me estoy perdiendo o haciendo mal?

EDIT:

A petición también estoy añadiendo código utilizado para serializar y deserializar:

Servidor:

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()); 
    } 

Cliente:

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; 
    } 

Deserialización se invoca con

StatusUpdate update = (StatusUpdate) Util.DeserializeXml(xmlData, typeof (StatusUpdate)); 
+1

La primera cosa que se está perdiendo no nos está mostrando el código que está utilizando para deserializar. –

+0

Esto todavía está incompleto. ¿De dónde viene la cadena 'xmlData' cuando se serializa como bytes en el otro extremo? No me sorprendería si esto es realmente un problema de codificación. ¿Y por qué su comentario menciona "utf-18" cuando no existe tal cosa? – Aaronaught

+0

En mi caso, fue por una declaración incorrecta de 'XmlSerializer'. Así que revisa eso también. – Mangesh

Respuesta

17

Después de muchas pruebas, finalmente encontré un error.No era un problema de codificación, ni el problema estaba en el otro código ni era el espacio de nombres que faltaba.

La parte faltante era la anotación del tipo de objetos en la matriz al deserializar.

así que tuve que cambiar mi clase StatusUpdate a

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

y la serialización comenzó a trabajar perfectamente.

Espero que ayude a alguien más.

1

Eso es realmente inusual de ver cuando se usa el XmlSerializer. El elemento raíz siempre debe tener este aspecto:

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

(Corrección: La XmlSerializerqué parecen funcionar sin estos en deserialización, pero siempre les añade en la serialización, así que algo de pescado si se pierden.)

Segunda edición:

tengo la fuerte sospecha de que su problema es la codificación relacionada. No sé por qué tiene que meterse con la serialización tanto y no se puede simplemente utilizar el valor predeterminado codificación UTF-8, pero independientemente, el siguiente código funciona sin errores:

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

Así que si algo es En su defecto, es muy probable que vaya mal durante la conversión de la matriz de bytes a la cadena XML en el lado del cliente. Ese es el único código que todavía no ha publicado.

3

aquí es lo resuelto por mí:

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