Serializzazione e metadati

Se l'applicazione serializza e deserializza oggetti, potrebbe essere necessario aggiungere voci al file di direttive di runtime (rd.xml) per assicurarsi che i metadati necessari siano presenti in fase di esecuzione. Esistono due categorie di serializzatori e ciascuna richiede una gestione differente nel file di direttive di runtime:

  • Serializzatori di terze parti basati su reflection. Richiedono modifiche al file di direttive di runtime e sono descritti nella sezione successiva.

  • Serializzatori basati su reflection trovati nella libreria di classi .NET Framework. Possono richiedere modifiche al file di direttive di runtime e sono descritti nella sezione Serializzatori Microsoft.

Serializzatori di terze parti

I serializzatori di terze parti, inclusi Newtonsoft.JSON, in genere sono basati su reflection. Dato un oggetto binario di grandi dimensioni (BLOB) di dati serializzati, i campi dati vengono assegnati a un tipo concreto cercando i campi del tipo di destinazione per nome. Come minimo, l'uso di queste librerie causa eccezioni MissingMetadataException per ogni oggetto Type che si prova a serializzare o deserializzare in una raccolta List<Type>.

Il modo più semplice per risolvere i problemi causati da metadati mancanti per questi serializzatori è raccogliere i tipi che verranno usati nella serializzazione in un singolo spazio dei nomi (ad esempio App.Models) e applicarvi una direttiva metadati Serialize:

<Namespace Name="App.Models" Serialize="Required PublicAndInternal" />

Per informazioni sulla sintassi usata in questo esempio, vedere <Elemento> Namespace.

Serializzatori Microsoft

Nonostante le classi DataContractSerializer, DataContractJsonSerializer e XmlSerializer non si basino sulla reflection, richiedono che il codice venga generato in base all'oggetto da serializzare o deserializzare. I costruttori di overload per ciascun serializzatore includono un parametro Type che specifica il tipo da serializzare o deserializzare. Il modo in cui si specifica che il tipo nel codice definisce l'azione che l'utente deve accettare, come illustrato nelle due sezioni.

typeof usato nel costruttore

Se si chiama un costruttore di queste classi di serializzazione e si include la parola chiave typeof di C# nella chiamata al metodo, non è necessario effettuare operazioni aggiuntive. Ad esempio, in ognuna delle seguenti chiamate a un costruttore di classe di serializzazione, la parola chiave typeof viene usata come parte dell'espressione passata al costruttore.

XmlSerializer xmlSer = new XmlSerializer(typeof(T));
DataContractSerializer dataSer = new DataContractSerializer(typeof(T));
DataContractJsonSerializer jsonSer = new DataContractJsonSerializer(typeof(T));

Il compilatore .NET Native gestirà automaticamente questo codice.

typeof usato fuori dal costruttore

Se si chiama un costruttore di queste classi di serializzazione e si usa la parola chiave typeof di C# fuori dall'espressione fornita al parametro Type del costruttore, come nel codice seguente, il compilatore di .NET Native non può risolvere il tipo:

Type t = typeof(DataSet);
XmlSerializer ser = new XmlSerializer(t);

In questo caso, è necessario specificare il tipo nel file di direttive di runtime con l'aggiunta di una voce simile alla seguente:

<Type Name="DataSet" Browse="Required Public" />

Analogamente, se si chiama un costruttore come XmlSerializer(Type, Type[]) e si fornisce una matrice di oggetti Type aggiuntivi da serializzare, come nel codice seguente, il compilatore di .NET Native non riesce a risolvere questi tipi.

XmlSerializer xSerializer = new XmlSerializer(typeof(Teacher),
                            new Type[] { typeof(Student),
                                         typeof(Course),
                                         typeof(Location) });

Aggiungere voci come le seguenti per ogni tipo al file di direttive di runtime:

<Type Name="t" Browse="Required Public" />

Per informazioni sulla sintassi usata in questo esempio, vedere <Elemento> Type.

Vedi anche