2013-11-15 19 views
6

Ho un curioso caso di questo problema di serializzazione - che è stato chiesto più volte su questo sito e ho passato alcune di queste domande e ho provato gli elementi usuali senza successo:tipo xxxx non previsto uso xmlinclude o soapinclude

  • Aggiungere [XmlInclude] alla classe gettando l'errore
  • Rimuovere gli spazi dei nomi
  • Aggiungi un namespace diverso per ogni classe

per spiegare ulteriormente, ho fornito una versione semplificata ver di seguito il mio codice. Essenzialmente sto usando un oggetto WebServiceHost per eseguire un servizio RESTful e uno dei miei endpoint restituisce un oggetto serializzato come XML (ho annotato l'oggetto con gli attributi [DataContract] e [DataMember]). Questo oggetto contiene SerializableDictionary<string, object> (here) dove il valore è stato digitato come object. Credo che questo sia il motivo per cui sta venendo a mancare:

  • funziona bene quando viene assegnato il valore di un primitivo
  • quando assegno un oggetto personalizzato per la coppia KV V, ottengo il tipo inaspettato eccezione probabilmente perché il Serializzatore non sa come serilaize l'oggetto/un qualche tipo di problema namespacing

Ovviamente, sono in grado di annotare Object.cs con [XmlInclude] sia perché è un servizio e io non sono me stesso serializzazione non posso usare qualcosa di simile

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

Qualche idea di cosa posso fare? Ho pensato di non digitare il valore di dict come oggetto e renderlo più concreto, ma il problema è che questo valore può assumere caratteri primitivi o cusotm. Del codice per spiegare quanto sopra:

Edit: Aggiornato il codice qui sotto per renderlo più chiaro

[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: L'errore è gettato in SerializableDictionary dove sta tentando di serializzare un oggetto di digitare ResponseObject. I due sono in progetti separati - se questo è significativo?

risposta

9

Normalmente, è necessario aggiungere un [XmlInclude] alla classe ResponseObject. In questo caso, non funziona a causa del SerializableDictionary che stai usando. Quella classe crea un altro XmlSerializer nella sua implementazione e, pertanto, non si preoccupa dei tuoi [XmlInclude]. Fondamentalmente non è in grado di gestire il tuo caso d'uso. È necessario passare da XmlSerializer a DataContractSerializer che gestisce la classe Dictionary e supporta l'attributo [KnownType] per registrare altri tipi: http://pastebin.com/vGLSaxHF. Si noti inoltre che è inutile aggiungere attributi [DataContract] e [DataMember] nel caso corrente perché XmlSerializer ignora tali attributi, vengono utilizzati solo da DataContractSerializer. Oppure, se non sei sicuro di come modificare il serializzatore (so che non lo sono), non dovresti utilizzare un dizionario o modificare l'implementazione SerializableDictionary per gestire i tipi di oggetti dinamici che desideri utilizzare (trova tutte le righe dove crea un nuovo XmlSerializer).Oppure, in alternativa, definire una classe base per tutti gli oggetti che si potrà mai mettere nel dizionario e fare in questo modo:

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

In questo modo, quando il SerializableDictionary crea la propria XmlSerializer, riconoscerà il AbstractBase e da lì, tutti i suoi discendenti.

+0

Cose geniali, molte grazie. Funziona a meraviglia. – clicky

Problemi correlati