2010-05-09 1 views
8

Ich habe ein Problem beim Versuch, die Klasse auf einem Server zu serialisieren, sende sie an den Client und Deserialize ist auf dem Ziel.xmlns = '' wurde beim Deserialisieren geschachtelter Klassen nicht erwartet

Auf dem Server ich die folgenden zwei Klassen:

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

und

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

(Die fehlenden Typen sind alle Aufzählungen).

Dies erzeugt das folgende XML-Serialisierung:

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

Auf der Client-Seite, bin ich versucht, dass in folgenden Klassen deserialisieren:

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

    } 

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

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

und

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

Der Deserializer löst jedoch eine Ausnahme aus:

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

Was vermisse ich oder mache ich falsch?

EDIT:

Auf Wunsch können auch verwendet Zugabe ich Code zu serialisieren und deserialisieren:

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

Auftraggeber:

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

Deserialisierung aufgerufen, mit

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

Das erste, was Sie fehlt nicht wird uns den Code zeigt Ihnen deserialisiert verwenden. –

+0

Dies ist immer noch unvollständig. Woher kommt der String 'xmlData', wenn er am anderen Ende als Bytes serialisiert wird? Ich wäre nicht überrascht, wenn es sich tatsächlich um ein Codierungsproblem handelt. Und warum erwähnt dein Kommentar "utf-18", wenn es so etwas nicht gibt? – Aaronaught

+0

In meinem Fall war es wegen der falschen Deklaration von 'XmlSerializer'. Also kontrolliere das auch. – Mangesh

Antwort

17

Nach vielen Tests habe ich endlich einen Fehler gefunden.Es war kein Codierungsproblem, weder das Problem im anderen Code noch der fehlende Namensraum.

Der fehlende Teil war die Annotation für den Typ der Objekte im Array beim Deserialisieren.

So hatte ich meine StatusUpdate Klasse

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

und Serialisierung begann perfekt arbeiten zu ändern.

Ich hoffe, dass jemand anderes hilft.

1

Das ist eigentlich sehr ungewöhnlich, wenn man den XmlSerializer benutzt. Das Wurzelelement sollte immer so aussehen:

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

(Korrektur: Die XmlSerializerhat erscheinen, ohne dass diese auf der Deserialisierung zu arbeiten, aber es fügt sie immer auf die Serialisierung, so etwas ist faul, wenn sie fehlen.)

Zweite edit:

ich stark vermuten, dass Ihr Problem ist bezogenen kodiert. Ich weiß nicht, warum Sie zu Chaos mit der Serialisierung haben so viel und kann nicht nur die Standard-UTF-8-Codierung verwenden, aber egal, der folgende Code funktioniert ohne Fehler:

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

Also, wenn etwas ist, fehlgeschlagen für Sie, es ist sehr wahrscheinlich falsch während der Konvertierung von Byte-Array in XML-Zeichenfolge auf der Client-Seite. Das ist der einzige Code, den du noch nicht gepostet hast.

3

hier ist, was es für mich gelöst:

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