2010-05-09 10 views
8

Ho un problema quando si tenta di serializzare la classe su un server, inviarlo al client e deserializzare è sulla destinazione.xmlns = '' non era previsto durante la deserializzazione delle classi nidificate

Sul server ho le seguenti due classi:

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

e

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

(I tipi mancanti sono tutti enumerazioni).

Questo genera il seguente codice XML sulla serializzazione:

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

Sul lato client, che sto tentando di deserializzare che nelle seguenti classi:

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

    } 

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

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

e

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

Tuttavia, il deserializzatore genera un'eccezione:

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

Cosa mi manca o cosa non funziona?

EDIT:

Su richiesta Sto anche l'aggiunta di codice utilizzato per serializzare e deserializzare:

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

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

deserializzazione viene richiamato con

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

La prima cosa che ti manca non ci mostra il codice che si sta utilizzando per deserializzare. –

+0

Questo è ancora incompleto. Da dove viene la stringa 'xmlData' quando è serializzata come byte sull'altra estremità? Non sarei sorpreso se questo fosse in realtà un problema di codifica. E perché il tuo commento menziona "utf-18" quando non esiste una cosa del genere? – Aaronaught

+0

Nel mio caso, era a causa della dichiarazione errata di 'XmlSerializer'. Quindi controlla anche questo. – Mangesh

risposta

17

Dopo un sacco di test ho finalmente trovato un errore.Non era un problema di codifica, né il problema era nell'altro codice né era lo spazio dei nomi mancante.

La parte mancante era l'annotazione per il tipo di oggetti nell'array durante la deserializzazione.

Così ho dovuto cambiare la mia classe 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; } 
} 

e serializzazione iniziato a lavorare perfettamente.

Spero che questo aiuti qualcun altro.

1

Questo è davvero molto insolito da vedere quando si utilizza il XmlSerializer. L'elemento radice deve sempre apparire come segue:

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

(Correzione: La XmlSerializerfa sembra funzionare senza questi su deserializzazione, ma li aggiunge sempre sulla serializzazione, quindi qualcosa di sospetto, se si perdono.)

seconda modifica:

ho il forte sospetto che il problema è la codifica-related. Non so il motivo per cui si deve fare confusione con la serializzazione tanto e non si può semplicemente utilizzare la codifica predefinita UTF-8, ma a prescindere, il seguente codice funziona senza errori:

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

Quindi, se c'è qualcosa che non in caso contrario, è molto probabile che si verifichi un errore durante la conversione dell'array di byte nella stringa XML sul lato client. Questo è l'unico codice che ancora non ha pubblicato.

3

qui è quello che ha risolto per me:

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