Domanda

Vorrei serializzare e deserializzare gli oggetti senza doversi preoccupare dell'intero grafico di classe.

La flessibilità è la chiave. Vorrei essere in grado di serializzare qualsiasi oggetto passato a me senza gli attributi completi necessari nell'intero grafico degli oggetti.

  

Ciò significa che la serializzazione binaria   non è un'opzione in quanto funziona solo con   le altre piattaforme .NET. Vorrei   piace anche qualcosa di leggibile da a   persona, e quindi decifrabile da a   programma di gestione e altro   interpreti.

Ho riscontrato problemi con i serializzatori DataContract, JSON e XML.

  • La maggior parte di questi errori sembra incentrata sulla serializzazione di elenchi / dizionari (ovvero Dizionario generico serializzabile XML ).
  • " Aggiungi qualsiasi tipo non noto staticamente all'elenco dei tipi noti - per esempio, usando il KnownTypeAttribute o l'attributo aggiungendoli all'elenco di noti tipi passati a DataContractSerializer ".

Basa le tue risposte su esperienze reali e non sulla teoria o sulla lettura di un articolo.

È stato utile?

Soluzione

Hai preso in considerazione la serializzazione su JSON anziché su XML?

Json.NET ha un serializzatore davvero potente e flessibile che non ha problemi con Hashtables / dizionari generici e non richiede attributi particolari. Lo so perché l'ho scritto :)

Ti dà un sacco di controllo attraverso varie opzioni sul serializzatore e ti permette di ignorare come un tipo viene serializzato creando un JsonConverter per esso.

Secondo me JSON è più leggibile dall'uomo rispetto a XML e Json.NET offre la possibilità di scrivere JSON ben formattato.

Finalmente il progetto è open source, quindi puoi entrare nel codice e apportare modifiche se necessario.

Altri suggerimenti

Se ricordo che funziona in questo modo con una proprietà:

[XmlArray("Foo")]
[XmlArrayItem("Bar")]
public List<BarClass> FooBars
{ get; set; }

Se lo serializzi, otterrai qualcosa del tipo:

<Foo>
    <Bar />
    <Bar />
</Foo>

Naturalmente, dovrei probabilmente rimandare agli esperti. Ecco ulteriori informazioni da MS: http: // msdn. microsoft.com/en-us/library/system.xml.serialization.xmlarrayitemattribute.aspx

Fammi sapere se funziona per te.

Dai tuoi requisiti sembra che la serializzazione Xml sia la migliore.

Che tipo di problemi hai con le raccolte durante la serializzazione? Se ti riferisci a non sapere quali attributi utilizzare in un Elenco o qualcosa di simile, potresti provare Attributo XmlArray sulla tua proprietà. Puoi sicuramente serializzare una collezione.

L'IntermediateSerializer in XNA Framework è dannatamente bello. Puoi trovare una serie di tutorial su come usarlo a http://blogs.msdn.com/shawnhar

La serializzazione SOAP ha funzionato bene per me, anche per oggetti non contrassegnati con [Serializable]

Avrai problemi con la serializzazione della raccolta se gli oggetti nella raccolta contengono riferimenti ad altri oggetti nella stessa raccolta. Se esiste un tipo di doppio puntamento, si finisce per creare una mappa multipla che non può essere serializzata. Su ogni problema che abbia mai avuto serializzare una raccolta personalizzata, è sempre stato a causa di alcune funzionalità aggiuntive che mi serviva che funzionava bene come parte di un "tipico" applicazione client-server, quindi fallita miseramente come parte di un'applicazione server-provider-consumatore.

Mettere tutte le classi che si desidera serializzare in un assembly separato, quindi utilizzare lo strumento sgen per generare un assembly di serializzazione per serializzare in XML. Utilizzare gli attributi XML per controllare la serializzazione.

Se è necessario personalizzare l'assembly di serializzazione (e sarà necessario per supportare le classi che non sono IXmlSerializable e le classi che contengono nodi astratti), allora istruire sgen a scaricare il codice sorgente in un file separato e quindi aggiungerlo alla soluzione. Quindi puoi modificarlo come necessario.

http://msdn.microsoft.com/ it-it / library / bk3w6240 (VS.80) aspx

FWIW, sono riuscito a serializzare l'intero Framework AdsML (oltre 400 classi) usando questa tecnica. Richiedeva molta personalizzazione manuale, ma non ci si può aggirare se si considera la dimensione del framework. (Ho usato uno strumento separato per passare da XSD a C #)

Sono d'accordo sul fatto che i metodi di serializzazione basati su DataContract (su JSON, XML, ecc.) siano un po 'più complessi di quanto vorrei.

Se stai cercando di ottenere JSON, controlla http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx

Fa parte delle estensioni MS AJAX. Certo, è contrassegnato come Obsoleto in .NET 3.5 ma ScottGu menziona qui il suo commento sul blog ( http://weblogs.asp.net/scottgu/archive/2007/10/01/tip-trick -building-a-tojson-extension-method-using-net-3-5.aspx # 4301973 ) che non è sicuro del perché e dovrebbe essere supportato per un po 'più a lungo.

La cosa più semplice da fare è contrassegnare i tuoi oggetti con l'attributo Serializable e quindi usare un formattatore binario per gestire la serializzazione. L'intero grafico di classe non dovrebbe essere un problema, a condizione che anche qualsiasi oggetto contenuto sia contrassegnato come Serializable.

Forse una via più efficiente sarebbe quella di serializzare usando BinaryFormatter

Come copiato da http://blog.paranoidferret.com/index.php/2007/04/27/csharp-tutorial-serialize-objects-to-a-file/

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

public class Serializer
{
   public Serializer()
   {
   }

   public void SerializeObject(string filename,
                  ObjectToSerialize objectToSerialize)
   {
      Stream stream = File.Open(filename, FileMode.Create);
      BinaryFormatter bFormatter = new BinaryFormatter();
      bFormatter.Serialize(stream, objectToSerialize);
      stream.Close();
   }

   public ObjectToSerialize DeSerializeObject(string filename)
   {
      ObjectToSerialize objectToSerialize;
      Stream stream = File.Open(filename, FileMode.Open);
      BinaryFormatter bFormatter = new BinaryFormatter();
      objectToSerialize =
         (ObjectToSerialize)bFormatter.Deserialize(stream);
      stream.Close();
      return objectToSerialize;
   }
}

Per l'interoperabilità abbiamo sempre usato la serializzazione Xml e ci siamo assicurati che la nostra classe fosse progettata da zero per farlo correttamente.

Creiamo un documento dello schema XSD e generiamo un insieme di classi da quello usando XSD.exe. Questo genera classi parziali, quindi creiamo un insieme di classi parziali corrispondenti per aggiungere i metodi extra che vogliamo aiutarci a popolare le classi e usarle nella nostra applicazione (poiché sono focalizzate sulla serializzazione e deserializzazione e sono un po 'difficili da usare a volte ).

È necessario utilizzare NetDataContractSerializer. Copre qualsiasi tipo di grafico a oggetti e supporta generici, elenchi, polimorfismi (l'attributo KnownType non è necessario qui), ricorsione ecc. L'unico inconveniente è che devi contrassegnare tutte le tue classi con gli attributi [Serializable] / [DataContract], ma l'esperienza dimostra che devi comunque eseguire una sorta di messa a punto manuale poiché non tutti i membri dovrebbero essere mantenuti. Inoltre serializza in un Xml, sebbene la sua leggibilità sia discutibile.

Avevamo gli stessi requisiti dei tuoi e abbiamo scelto questa soluzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top