Introduzione alla serializzazione XML
La serializzazione è il processo di conversione di un oggetto in un form che può essere immediatamente trasportato. È possibile, ad esempio, serializzare un oggetto e trasportarlo in Internet mediante HTTP tra un client e un server. La deserializzazione invece ricostruisce l'oggetto dal flusso.
La serializzazione XML serializza solo i valori delle proprietà e dei campi pubblici di un oggetto in un flusso XML e non include informazioni sul tipo. Se ad esempio si dispone di un oggetto Book che esiste nello spazio dei nomi Library, non si ha la certezza che venga deserializzato in un oggetto dello stesso tipo.
Nota
La serializzazione XML non converte metodi, indicizzatori, campi privati o proprietà di sola lettura, ad eccezione degli insiemi di sola lettura. Per serializzare tutti i campi e le proprietà di un oggetto, pubblici e privati, utilizzare BinaryFormatter anziché la serializzazione XML.
La classe centrale nella serializzazione XML è la classe XmlSerializer, i cui metodi più importanti sono Serialize e Deserialize. XmlSerializer consente di creare file C# e compilarli in file con estensione dll per eseguire la serializzazione. In .NET Framework 2.0 XML Serializer Generator Tool (Sgen.exe) è progettato per generare in anticipo gli assembly di serializzazione da distribuire con l'applicazione e migliorare le prestazioni di avvio. Il flusso XML generato da XmlSerializer è conforme alla raccomandazione sul linguaggio di definizione dello schema XML (XSD) 1.0 del World Wide Web Consortium (www.w3.org) (informazioni in lingua inglese). I tipi di dati generati sono inoltre conformi al documento "XML Schema Part 2: Datatypes" (informazioni in lingua inglese).
I dati contenuti negli oggetti vengono descritti tramite costrutti del linguaggio di programmazione come classi, campi, proprietà, tipi primitivi, matrici, nonché come linguaggio XML incorporato sotto forma di oggetti XmlElement o XmlAttribute. È possibile creare classi personalizzate annotate con attributi oppure utilizzare lo strumento di definizione di schemi XML per generare le classi basate su uno schema XML esistente.
Se si dispone di uno schema XML, è possibile eseguire lo strumento di definizione di schemi XML per generare un gruppo di classi tipizzate in modo sicuro rispetto allo schema e annotate con attributi. Quando viene serializzata un'istanza di una classe del genere, il linguaggio XML generato è conforme allo schema XML. Se si dispone di una classe di tale genere, è possibile programmare a fronte di un modello a oggetti facilmente manipolabile con la certezza che il linguaggio XML generato sia conforme allo schema XML. Questa è un'alternativa all'utilizzo di altre classi in .NET Framework, ad esempio XmlReader e XmlWriter, per analizzare e scrivere un flusso XML. Per ulteriori informazioni, vedere Documenti e dati XML. Le classi consentono di analizzare qualsiasi flusso XML. Utilizzare invece XmlSerializer quando si prevede che il flusso XML sia conforme a uno schema XML noto.
Gli attributi controllano il flusso XML generato dalla classe XmlSerializer consentendo di impostare lo spazio dei nomi XML, il nome dell'elemento, il nome dell'attributo e altri componenti del flusso XML. Per ulteriori informazioni su questi attributi e su come controllano la serializzazione XML, vedere Controllo della serializzazione XML mediante attributi. Per una tabella degli attributi utilizzati per controllare il codice XML generato, vedere Attributi che controllano la serializzazione XML.
La classe XmlSerializer può eseguire un'ulteriore serializzazione di un oggetto e generare un flusso XML SOAP codificato. Il linguaggio XML generato è conforme alla sezione 5 del documento "Simple Object Access Protocol (SOAP) 1.1" del World Wide Web Consortium (informazioni in lingua inglese). Per ulteriori informazioni su questo processo, vedere Procedura: serializzare un oggetto come flusso XML con codifica SOAP. Per una tabella degli attributi che controllano il codice XML generato, vedere Attributi che controllano la serializzazione con codifica SOAP.
La classe XmlSerializer genera i messaggi SOAP creati da servizi Web XML e passati a servizi Web XML. Per controllare i messaggi SOAP, è possibile applicare gli attributi classi, valori restituiti, parametri e campi trovati in un file del servizio Web XML, con estensione asmx. È possibile utilizzare entrambi gli attributi indicati negli argomenti Attributi che controllano la serializzazione XML e Attributi che controllano la serializzazione con codifica SOAP poiché un servizio Web XML può utilizzare lo stile letterale o quello con codifica SOAP. Per ulteriori informazioni sull'utilizzo degli attributi per il controllo del codice XML generato da un servizio Web XML, vedere Serializzazione XML mediante servizi Web XML. Per ulteriori informazioni su SOAP e sui servizi Web XML, vedere Personalizzazione della formattazione di messaggi SOAP.
Considerazioni sulla protezione per applicazioni XmlSerializer
Quando si crea un'applicazione in cui viene utilizzata la classe XmlSerializer, è necessario conoscere gli elementi seguenti e le relative implicazioni:
XmlSerializer consente di creare file C# (con estensione cs) e di compilarli in file con estensione dll nella directory denominata dalla variabile di ambiente TEMP. La serializzazione avviene tramite tali DLL.
Nota
Questi assembly di serializzazione possono essere generati in anticipo e firmati utilizzando lo strumento SGen.exe. La procedura non è supportata per il lato server dei servizi Web, ovvero è disponibile solo per il lato client e per la serializzazione manuale.
Il codice e le DLL sono esposti a processi non autorizzati in fase di creazione e compilazione. Quando si utilizza un computer in cui viene eseguito Microsoft Windows NT 4.0 o versione successiva, due o più utenti potrebbero condividere la directory temp. Condividere una directory temp è una pericoloso se i due account dispongono di privilegi di protezione diversi e l'account con i privilegi superiori esegue un'applicazione che utilizza XmlSerializer. In tal caso, un utente può violare la protezione del computer sostituendo il file con estensione cs o dll compilato. Per risolvere il problema, assicurarsi sempre che ogni account nel computer disponga di uno specifico profilo. Per impostazione predefinita, la variabile di ambiente TEMP fa riferimento a una directory diversa per ogni account.
Se un utente malintenzionato invia un flusso continuo di dati XML a un server Web (attacco Denial of Service), XmlSerializer continua a elaborare i dati finché le risorse del computer non diventano insufficienti.
Questo tipo di attacco viene eliminato se si utilizza un computer in cui viene eseguito IIS (Internet Information Services) e l'applicazione viene eseguita all'interno di IIS. IIS include un gate che non consente l'elaborazione di flussi più lunghi del valore impostato (4 KB per impostazione predefinita). Se si crea un'applicazione che non utilizza IIS e in cui la deserializzazione viene eseguita con XmlSerializer, è necessario implementare un gate simile per evitare gli attacchi Denial of Service.
XmlSerializer consente di serializzare i dati e di eseguire qualsiasi codice tramite qualunque tipo assegnato.
Un oggetto dannoso presenta due tipi di minaccia. È possibile che venga eseguito malware o che il malware venga inserito nel file C# creato da XmlSerializer. Nel primo caso, se un oggetto non dannoso cerca di eseguire una procedura distruttiva, la protezione dall'accesso di codice evita qualsiasi tipo di danno. Nel secondo caso, esiste in teoria la possibilità che un oggetto dannoso inserisca il codice nel file C# creato da XmlSerializer. Sebbene questo problema sia stato esaminato con attenzione e la possibilità di questo tipo di attacco sia remota, è opportuno non serializzare i dati tramite un tipo sconosciuto e non attendibile.
I dati sensibili serializzati possono essere esposti ad attacchi.
Dopo che XmlSerializer ha serializzato i dati, può essere archiviato come file XML o un altro tipo di archivio dati. Se l'archivio dati è utilizzato per altri processi o è visibile in una Intranet o in Internet, i dati possono venire prelevati e manomessi. Se, ad esempio, si crea un'applicazione che serializza ordini che includono numeri di carte di credito, i dati sono estremamente riservati. Per evitare che i dati vengano prelevati e manomessi, proteggere sempre l'archivio dati e garantirne la riservatezza.
Serializzazione di una classe semplice
Nell'esempio di codice seguente viene illustrata una classe semplice con un campo pubblico.
Public Class OrderForm
Public OrderDate As DateTime
End Class
public class OrderForm
{
public DateTime OrderDate;
}
Quando un'istanza di questa classe viene serializzata, potrebbe essere simile alla seguente.
<OrderForm>
<OrderDate>12/12/01</OrderDate>
</OrderForm>
Per ulteriori esempi di serializzazione, vedere Esempi di serializzazione XML.
Elementi serializzabili
Gli elementi seguenti possono essere serializzati utilizzando la classe XmLSerializer:
Proprietà di lettura/scrittura pubbliche e campi di classi pubbliche
Classi che implementano ICollection o IEnumerable
Nota
È possibile serializzare solo gli insiemi, non le proprietà pubbliche.
Oggetti XmlElement
Oggetti XmlNode
Oggetti DataSet
Per ulteriori informazioni sulla serializzazione o la deserializzazione di oggetti, vedere Procedura: serializzare un oggetto e Procedura: deserializzare un oggetto.
Vantaggi dell'utilizzo della serializzazione XML
La classe XmlSerializer offre un controllo completo e flessibile quando si serializza un oggetto come XML. Se si crea un servizio Web XML, è possibile applicare gli attributi che controllano la serializzazione a classi e membri per garantire che l'output XML sia conforme a uno schema specifico.
XmlSerializer, ad esempio, consente di:
Specificare se un campo o una proprietà deve essere codificata come attributo o elemento.
Specificare uno spazio dei nomi XML da utilizzare.
Specificare il nome di un elemento o attributo se il nome di un campo o di una proprietà non è corretto.
Un altro vantaggio della serializzazione XML è costituito dall'assenza di vincoli sulle applicazioni sviluppate, purché il flusso XML generato sia conforme a uno specifico schema. Uno schema utilizzato per descrivere libri, ad esempio, include titolo, autore, editore e numero ISBN. È possibile sviluppare un'applicazione che elabora i dati XML nel modo desiderato, ad esempio come ordine o inventario di libri. In entrambi i casi l'unico requisito è che il flusso XML sia conforme al linguaggio di definizione dello schema XML (XSD) specificato.
Considerazioni sulla serializzazione XML
Durante l'utilizzo della classe XmlSerializer è necessario tenere conto di quanto segue:
Lo strumento Sgen.exe è progettato specificamente per generare assembly di serializzazione per prestazioni ottimali.
I dati serializzati contengono solo i dati stessi e la struttura delle classi. L'identità del tipo e le informazioni dell'assembly non vengono incluse.
È possibile serializzare solo le proprietà e i campi pubblici. Se è necessario serializzare dati non pubblici, utilizzare la classe BinaryFormatter anziché la serializzazione XML.
Una classe deve avere un costruttore predefinito serializzabile da XmlSerializer.
Non è possibile serializzare i metodi.
XmlSerializer consente di elaborare in modo diverso classi che implementano IEnumerable o ICollection purché soddisfino i requisiti specifici descritti di seguito.
Una classe che implementa IEnumerable deve implementare un metodo Add pubblico che accetta un solo parametro. Il parametro del metodo Add deve essere coerente, ovvero polimorfico, con il tipo restituito dalla proprietà IEnumerator.Current restituita dal metodo GetEnumerator.
Una classe che implementa ICollection oltre a IEnumerable, ad esempio CollectionBase, deve avere una proprietà indicizzata Item pubblica (un indicizzatore in C#) che accetta un valore integer e deve disporre di una proprietà Count pubblica di tipo integer. Il parametro passato al metodo Add deve corrispondere al tipo restituito dalla proprietà Item o a una delle basi di tale tipo.
Per le classi che implementano ICollection, i valori da serializzare vengono recuperati dalla proprietà Item indicizzata anziché la chiamata a GetEnumerator. Le proprietà e i campi pubblici inoltre non vengono serializzati, con l'eccezione dei campi pubblici che restituiscono un'altra classe dell'insieme, ovvero una classe che implementa ICollection. Per un esempio, vedere Esempi di serializzazione XML.
Mapping dei tipi di dati XSD
Nel documento "XML Schema Part 2: Datatypes" del World Wide Web Consortium (www.w3.org) (informazioni in lingua inglese) vengono specificati i tipi di dati semplici consentiti in uno schema del linguaggio di definizione dello schema XML (XSD). Per molti di essi, ad esempio int e decimal, esiste un tipo di dati corrispondente in .NET Framework. Alcuni tipi di dati XML, ad esempio NMTOKEN non hanno un corrispondente in .NET Framework. In questi casi, se si utilizza lo strumento di definizione di schemi XML (XML Schema Definition Tool (Xsd.exe)) per generare classi da uno schema, un attributo appropriato viene applicato a un membro di tipo String e la rispettiva proprietà DataType viene impostata sul nome del tipo di dati XML. Se, ad esempio, uno schema contiene un elemento denominato "MyToken" con il tipo di dati XML NMTOKEN, la classe generata potrebbe contenere un membro, come illustrato nell'esempio seguente.
<XmlElement(DataType:="NMTOKEN")> _
Public MyToken As String
[XmlElement(DataType = "NMTOKEN")]
public string MyToken;
In modo analogo, se si crea una classe che deve essere conforme a uno schema XML (XSD) specifico, è necessario applicare l'attributo appropriato e impostarne la proprietà DataType sul nome del tipo di dati XML desiderato.
Per un elenco completo dei mapping dei tipi, vedere la proprietà DataType per le classi di attributi seguenti:
Vedere anche
Attività
Procedura: serializzare un oggetto
Procedura: deserializzare un oggetto
Riferimenti
XMLSerializer.Serialize
BinaryFormatter
XmlSerializer
FileStream
Concetti
Altre risorse
Serializzazione XML e SOAP
Serializzazione binaria
Serializzazione