2013-11-15 6 views
6

Ich habe einen seltsamen Fall dieses Serialisierungsproblems - das wurde oft auf dieser Seite gefragt und ich habe ein paar dieser Fragen durchgelaufen und habe die üblichen Dinge vergeblich versucht:Typ xxxx nicht zu verwenden xmlinclude oder soapinclude

  • hinzufügen [XmlInclude], um die Klasse zu werfen die Fehler
  • entfernen Namespaces
  • einen anderen Namespace

jede Klasse hinzufügen weiter zu erklären, ich habe eine vereinfachte vorgesehen ver sion meines Codes unten. Im Wesentlichen benutze ich ein Objekt WebServiceHost, um einen RESTful-Dienst auszuführen, und einer meiner Endpunkte gibt ein als XML serialisiertes Objekt zurück (ich habe das Objekt mit den Attributen [DataContract] und [DataMember] annotiert). Dieses Objekt enthält eine (here), wobei der Wert als object eingegeben wurde. Ich glaube, das ist, warum es fehlschlägt:

  • funktioniert gut, wenn der Wert zugewiesen ist ein primitiver
  • Wenn ich ein benutzerdefiniertes Objekt mit dem KV Paar V zuweisen, erhalte ich die unerwartete Art Ausnahme wahrscheinlich, weil die Serializer nicht weiß, wie das Objekt serilaize/irgendeine Art von Problem Namensräume

Offensichtlich bin ich nicht in der Lage Object.cs mit [XmlInclude] zu annotieren und weil es ist ein Dienst, und ich bin nicht ich selbst Serialisierung ich etwas nicht verwendet, kann wie

new Serializer(typeof(...), new Type[] { ... }} 

Irgendeine Idee, was ich tun kann? Ich habe darüber nachgedacht, den dict-Wert nicht als Objekt einzugeben, sondern eher konkreter, aber das Problem ist, dass dieser Wert Primitive oder Cusotm-Typen annehmen kann. Einiger Code zu erklären, die oben:

Edit: der Code unten aktualisiert, um es deutlicher

[DataContract] 
public class ResponseObject 
{ 
    [DataMember(Name = "data")] 
    public SerializableDictionary<string, object> Data { get;set; } 

    public ResponseObject() 
    { 
     Data = new SerializableDictionary<string, object>(); 
    } 
} 

... 

var d1 = new ResponseObject(); 
d1.Data.Add("some key", "some value"); //WORKS AND SERIALIZES PERFECLTY 

var d2 = new ResponseObject(); 
d2.Data.Add("some other key", new SomeOtherObjecT()); 
var d3 = new ResponseObject(); 
d3.Data.Add("another key", d2); //THIS THROWS THE UNEXPECTED TYPE ERROR WHEN SEIRLAIZING SomeOtherObject 

Edit: Der Fehler in SerializableDictionary geworfen wird, wo er versucht, ein Objekt zu serialisieren Typ ResponseObject. Die beiden sind in getrennten Projekten - wenn das wichtig ist?

Antwort

9

Normalerweise sollten Sie der ResponseObject-Klasse einen [XmlInclude] hinzufügen. In diesem Fall funktioniert es aufgrund des von Ihnen verwendeten SerializableDictionary nicht. Diese Klasse erstellt in ihrer Implementierung einen weiteren XmlSerializer und kümmert sich daher nicht um Ihre [XmlInclude]. Grundsätzlich kann es Ihren Anwendungsfall nicht verarbeiten. Sie sollten von XmlSerializer auf den DataContractSerializer umschalten, der die Dictionary-Klasse verarbeitet und das Attribut [KnownType] unterstützt, um weitere Typen zu registrieren: http://pastebin.com/vGLSaxHF. Beachten Sie auch, dass es im aktuellen Fall sinnlos ist, die Attribute [DataContract] und [DataMember] hinzuzufügen, da der XmlSerializer diese Attribute ignoriert und nur vom DataContractSerializer verwendet wird. Oder wenn Sie nicht sicher sind, wie Sie Ihren Serializer ändern (ich weiß, dass ich nicht bin), dann sollten Sie entweder kein Dictionary verwenden oder die SerializableDictionary-Implementierung ändern, um die dynamischen Objekttypen zu behandeln, die Sie verwenden möchten es erstellt einen neuen XmlSerializer).Oder als Alternative, definieren Sie eine Basisklasse für alle Objekte, die Sie jemals in das Wörterbuch gesetzt wird und tun es wie folgt aus:

[XmlInclude(typeof(Class1), XmlInclude(typeof(Class2)), etc] 
public class AbstractBase { } 

public class Class1 : AbstractBase { ... } 

public class Class2 : AbstractBase { ... } 

public class BigClass { 
    public SerializableDictionary<string, AbstractBase> Dictionary { get; set; } 
} 

Auf diese Weise, wenn die SerializableDictionary seinen eigenen XmlSerializer erstellt, wird es erkennen, die AbstractBase und von dort, alle seine Nachkommen.

+0

Brilliantes Zeug, vielen Dank. Funktioniert gut. – clicky

Verwandte Themen