Serializzazione e deserializzazione
In Windows Communication Foundation (WCF) è disponibile un nuovo motore di serializzazione, ovvero DataContractSerializer. DataContractSerializer esegue la conversione tra oggetti .NET Framework e XML in entrambe le direzioni. In questo argomento viene illustrato il funzionamento del serializzatore.
Durante la serializzazione di oggetti .NET Framework, il serializzatore è in grado di comprendere numerosi modelli di programmazione della serializzazione, incluso il nuovo modello di contratto dati. Per un elenco completo dei tipi supportati, vedere Tipi supportati dal serializzatore dei contratti dati. Per un'introduzione ai contratti dati, vedere Utilizzo di contratti dati.
Durante la deserializzazione di XML, il serializzatore utilizza le classi XmlReader e XmlWriter. Supporta inoltre le classi XmlDictionaryReader e XmlDictionaryWriter per produrre, in alcuni casi, XML ottimizzato, ad esempio quando viene utilizzato il formato XML binario di WCF.
WCF include anche un serializzatore complementare, NetDataContractSerializer. NetDataContractSerializer è simile ai serializzatori BinaryFormatter e SoapFormatter perché emette anche nomi di tipo .NET Framework come parte dei dati serializzati. Viene utilizzato quando gli stessi tipi sono condivisi alle estremità di serializzazione e deserializzazione. Sia DataContractSerializer che NetDataContractSerializer derivano da una classe di base comune, XmlObjectSerializer.
Attenzione: |
---|
DataContractSerializer serializza stringhe che contengono caratteri di controllo con un valore esadecimale inferiore a 20 come entità XML. Questa situazione potrebbe provocare un problema con un client non WCF durante l'invio di dati di questo tipo a un servizio WCF. |
Creazione di un'istanza DataContractSerializer
La creazione di un'istanza di DataContractSerializer è un passaggio importante. Dopo la costruzione, non è possibile modificare nessuna di queste impostazioni.
Specifica del tipo radice
Il tipo radice è il tipo delle istanze che vengono serializzate o deserializzate. DataContractSerializer ha numerosi overload del costruttore, tuttavia è necessario fornire almeno un tipo radice utilizzando il parametro type .
Un serializzatore creato per un certo tipo radice non può essere utilizzato per serializzare (o deserializzare) un altro tipo, a meno che il tipo non sia derivato dal tipo radice. Nell'esempio che segue vengono illustrate due classi.
<DataContract()> _
Public Class Person
' Code not shown.
End Class
<DataContract()> _
Public Class PurchaseOrder
' Code not shown.
End Class
[DataContract]
public class Person
{
// Code not shown.
}
[DataContract]
public class PurchaseOrder
{
// Code not shown.
}
Questo codice costruisce un'istanza di DataContractSerializer che può essere utilizzata solo per serializzare o deserializzare istanze della classe Person
.
Dim dcs As New DataContractSerializer(GetType(Person))
'This can now be used to serialize/deserialize Person but not PurchaseOrder.
DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
//This can now be used to serialize/deserialize Person but not PurchaseOrder.
Specifica di tipi conosciuti
Se i tipi serializzati implicano un polimorfismo che non è già gestito utilizzando l'attributo KnownTypeAttribute o un qualche altro meccanismo, è necessario passare al costruttore del serializzatore un elenco di possibili tipi conosciuti utilizzando il parametro knownTypes. Per ulteriori informazioni su tipi conosciuti, vedere Tipi conosciuti di contratto dati.
Nell'esempio di codice seguente viene illustrata una classe, LibraryPatron
, che comprende una raccolta di un tipo specifico LibraryItem
. La seconda classe definisce il tipo LibraryItem
. La terza e la quarta classe, Book
e Newspaper
, ereditano dalla classe LibraryItem
.
<DataContract()> _
Public Class LibraryPatron
<DataMember()> _
Public borrowedItems() As LibraryItem
End Class
<DataContract()> _
Public Class LibraryItem
'code not shown
End Class 'LibraryItem
<DataContract()> _
Public Class Book
Inherits LibraryItem
'code not shown
End Class
<DataContract()> _
Public Class Newspaper
Inherits LibraryItem
'code not shown
End Class
Nel codice seguente viene creata un'istanza del serializzatore utilizzando il parametro knownTypes.
'Create a serializer for the inherited types using the knownType parameter.
Dim knownTypes() As Type = {GetType(Book), GetType(Newspaper)}
Dim dcs As New DataContractSerializer(GetType(LibraryPatron), knownTypes)
' All types are known after construction.
//Create a serializer for the inherited types using the knownType parameter.
Type[] knownTypes = new Type[] { typeof(Book), typeof(Newspaper) };
DataContractSerializer dcs =
new DataContractSerializer(typeof(LibraryPatron), knownTypes);
// All types are known after construction.
Specifica del nome principale e dello spazio dei nomi predefiniti
In genere, quando un oggetto viene serializzato, il nome e lo spazio dei nomi predefiniti dell'elemento XML più esterno vengono determinati in base al nome del contratto dati e allo spazio dei nomi. I nomi di tutti gli elementi interni vengono determinati dai nomi dei membri dati e il loro spazio dei nomi è lo spazio dei nomi del contratto dati. Nell'esempio seguente vengono impostati i valori Name
e Namespace
nei costruttori delle classi DataContractAttribute e DataMemberAttribute.
<DataContract(Name := "PersonContract", [Namespace] := "http://schemas.contoso.com")> _
Public Class Person2
<DataMember(Name := "AddressMember")> _
Public theAddress As Address
End Class
<DataContract(Name := "AddressContract", [Namespace] := "http://schemas.contoso.com")> _
Public Class Address
<DataMember(Name := "StreetMember")> _
Public street As String
End Class
[DataContract(Name = "PersonContract", Namespace = "http://schemas.contoso.com")]
public class Person2
{
[DataMember(Name = "AddressMember")]
public Address theAddress;
}
[DataContract(Name = "AddressContract", Namespace = "http://schemas.contoso.com")]
public class Address
{
[DataMember(Name = "StreetMember")]
public string street;
}
La serializzazione di un'istanza della classe Person
produce un XML simile al seguente.
<PersonContract xmlns="http://schemas.contoso.com">
<AddressMember>
<StreetMember>123 Main Street</StreetMember>
</AddressMember>
</PersonContract>
È tuttavia possibile personalizzare il nome e lo spazio dei nomi predefiniti dell'elemento radice passando i valori dei parametri rootName e rootNamespace al costruttore DataContractSerializer. Si noti che rootNamespace non influisce sullo spazio dei nomi degli elementi contenuti che corrispondono ai membri dati. Influisce solo sullo spazio dei nomi dell'elemento più esterno.
Questi valori possono essere passati come stringhe o come istanze della classe XmlDictionaryString per consentire la loro ottimizzazione utilizzando il formato XML binario.
Impostazione della quota massima di oggetti
Alcuni overload del costruttore DataContractSerializer hanno un parametro maxItemsInObjectGraph. Tale parametro determina il numero massimo di oggetti serializzati o deserializzati dal serializzatore in una singola chiamata al metodo ReadObject. Questo metodo legge sempre un oggetto radice che, tuttavia, potrebbe contenere altri oggetti come membri dei propri dati. Tali oggetti possono a loro volta contenere altri oggetti, e così via. Il valore predefinito è 65536. Si noti che, in caso di serializzazione o deserializzazione di matrici, ogni elemento della matrice viene considerato come un oggetto separato. Inoltre, poiché per alcuni oggetti è possibile una vasta rappresentazione in memoria, tale quota da sola potrebbe non essere sufficiente per impedire attacchi di tipo Denial of Service. Per ulteriori informazioni, vedere Considerazioni sulla protezione per i dati. Se è necessario aumentare la quota oltre il valore predefinito, è importante aumentarla sia sul lato di invio (serializzazione) sia su quello di ricezione (deserializzazione) poiché si applica sia durante la lettura che durante la scrittura dei dati.
Percorsi di andata e ritorno
Si verifica un percorso di andata e ritorno quando un oggetto viene deserializzato e serializzato di nuovo in un'unica operazione. Pertanto, passa da XML a un'istanza dell'oggetto e torna indietro in un flusso XML.
Alcuni overload del costruttore DataContractSerializer hanno un parametro ignoreExtensionDataObject , la cui impostazione predefinita è false . In questa modalità predefinita, è possibile inviare i dati su un percorso di andata e ritorno da una versione più recente di un contratto dati a una versione precedente e di nuovo indietro alla versione più recente senza alcuna perdita, a condizione che il contratto dati implementi l'interfaccia IExtensibleDataObject. Si supponga, ad esempio, che la versione 1 del contratto dati Person
contenga i membri dati Name
e PhoneNumber
e che la versione 2 aggiunga un membro Nickname
. Se IExtensibleDataObject è implementato, durante l'invio di informazioni dalla versione 2 alla versione 1 i dati Nickname
vengono memorizzati e vengono emessi di nuovo alla successiva serializzazione., senza andare persi nel percorso di andata e ritorno. Per ulteriori informazioni, vedere Contratti dati compatibili con versioni successive e Controllo delle versioni dei contratti dati.
Problemi di sicurezza e validità dello schema in caso di percorsi di andata e ritorno
I percorsi di andata e ritorno possono avere implicazioni di sicurezza. La deserializzazione e memorizzazione di grandi quantità di dati estranei, ad esempio, possono rappresentare un rischio per la protezione. Possono esservi problemi di sicurezza quando vengono emessi di nuovo dati che non è assolutamente possibile verificare, specie se implicano firme digitali. Nello scenario precedente, ad esempio, l'endpoint della versione 1 potrebbe firmare un valore Nickname
che contiene dati dannosi. Infine, potrebbero verificarsi problemi di validità dello schema poiché un endpoint potrebbe desiderare di emettere sempre dati strettamente conformi al contratto dichiarato e nessun valore aggiuntivo. Nell'esempio precedente, il contratto dell'endpoint della versione 1 asserisce che emette solo Name
e PhoneNumber
e, se viene utilizzata la convalida dello schema, l'emissione del valore Nickname
aggiuntivo causa l'insuccesso della convalida.
Attivazione e disattivazione di percorsi di andata e ritorno
Per disattivare i percorsi di andata e ritorno, non implementare l'interfaccia IExtensibleDataObject. Se non si ha alcun controllo sui tipi, impostare il parametro ignoreExtensionDataObject su true per ottenere lo stesso effetto.
Conservazione dell'oggetto grafico
In genere, il serializzatore non si preoccupa dell'identità dell'oggetto, come illustrato nel codice seguente.
<DataContract()> _
Public Class PurchaseOrder
<DataMember()> _
Public billTo As Address
<DataMember()> _
Public shipTo As Address
End Class
<DataContract()> _
Public Class Address
<DataMember()> _
Public street As String
End Class
[DataContract]
public class PurchaseOrder
{
[DataMember]
public Address billTo;
[DataMember]
public Address shipTo;
}
[DataContract]
public class Address
{
[DataMember]
public string street;
}
Nel codice seguente viene creato un ordine di acquisto.
'Construct a purchase order:
Dim adr As New Address()
adr.street = "123 Main St."
Dim po As New PurchaseOrder()
po.billTo = adr
po.shipTo = adr
//Construct a purchase order:
Address adr = new Address();
adr.street = "123 Main St.";
PurchaseOrder po = new PurchaseOrder();
po.billTo = adr;
po.shipTo = adr;
Si noti che i campi billTo
e shipTo
sono impostati sulla stessa istanza dell'oggetto. L'XML generato, tuttavia, duplica le informazioni duplicate ed è simile all'XML seguente.
<PurchaseOrder>
<billTo><street>123 Main St.</street></billTo>
<shipTo><street>123 Main St.</street></shipTo>
</PurchaseOrder>
Questo approccio ha tuttavia le caratteristiche seguenti, che potrebbero essere indesiderate:
Prestazioni. Replicare i dati non è efficiente.
Riferimenti circolari. Se gli oggetti fanno riferimento a se stessi, anche tramite altri oggetti, la serializzazione tramite la replica comporta un ciclo infinito. In questo caso, il serializzatore genera una SerializationException.
Semantica. Talvolta è importante mantenere due riferimenti allo stesso oggetto e non a due oggetti identici.
Per queste ragioni, alcuni overload del costruttore DataContractSerializer hanno un parametro preserveObjectReferences (l'impostazione predefinita è false). Quando questo parametro è impostato su true, viene utilizzato un metodo speciale di codificare i riferimenti all'oggetto, che solo WCF comprende. Quando è impostato su true, l'esempio di codice XML è simile al seguente.
<PurchaseOrder ser:id="1">
<billTo ser:id="2"><street ser:id="3">123 Main St.</street></billTo>
<shipTo ser:ref="2"/>
</PurchaseOrder>
Lo spazio dei nomi "ser" si riferisce allo spazio dei nomi della serializzazione standard, https://schemas.microsoft.com/2003/10/Serialization/. Ogni blocco di dati viene serializzato solo una volta e gli viene fornito un numero ID. Gli utilizzi successivi comportano un riferimento ai dati già serializzati.
Nota: |
---|
Se entrambi gli attributi "id" e "ref" sono presenti nel contratto dati XMLElement, l'attributo "ref" viene rispettato e l'attributo "id" viene ignorato. |
È importante capire le limitazioni di questa modalità:
L'XML prodotto da DataContractSerializer con preserveObjectReferences impostato su true non è interoperativo con nessun'altra tecnologia ed è possibile accedervi solo da un'altra istanza DataContractSerializer, anche con preserveObjectReferences impostato su true.
Non esiste supporto di metadati (schema) per questa funzionalità. Lo schema prodotto è valido solo quando preserveObjectReferences è impostato su false.
Questa funzionalità può rallentare il processo di serializzazione e di deserializzazione. Anche se i dati non devono essere replicati, i confronti degli oggetti aggiuntivi devono essere eseguiti in questa modalità.
Attenzione: |
---|
Quando la modalità preserveObjectReferences è attivata, è particolarmente importante impostare il valore maxItemsInObjectGraph sulla quota corretta. A causa del modo in cui le matrici sono gestite in questa modalità, è facile per l'autore di un attacco costruire un piccolo messaggio dannoso che comporta un grande consumo di memoria limitato solo dalla quota maxItemsInObjectGraph. |
Specifica di un surrogato del contratto dati
Alcuni overload del costruttore DataContractSerializer hanno un parametro dataContractSurrogate che può essere impostato su null. In caso contrario, è possibile utilizzarlo per specificare un surrogato del contratto dati che è un tipo che implementa l'interfaccia IDataContractSurrogate. È quindi possibile utilizzare l'interfaccia per personalizzare il processo di serializzazione e di deserializzazione. Per ulteriori informazioni, vedere Surrogati del contratto dati.
Serializzazione
Le informazioni seguenti si applicano a qualsiasi classe che eredita da XmlObjectSerializer, incluse le classi DataContractSerializer e NetDataContractSerializer.
Serializzazione semplice
La modalità più elementare per serializzare un oggetto consiste nel passarlo al metodo WriteObject. Esistono tre overload, per scrivere rispettivamente in un Stream, in un XmlWriter o in un XmlDictionaryWriter. Con l'overload Stream, l'output è XML nella codifica UTF-8. Con l'overload XmlDictionaryWriter, il serializzatore ottimizza l'output per XML binario.
Quando si utilizza il metodo WriteObject, il serializzatore utilizza il nome e lo spazio dei nomi predefiniti per l'elemento wrapper e lo scrive insieme al contenuto (vedere la sezione precedente "Specifica del nome principale e dello spazio dei nomi predefiniti").
Nell'esempio seguente viene illustrato come scrivere con XmlDictionaryWriter.
Dim p As New Person()
Dim dcs As New DataContractSerializer(GetType(Person))
Dim xdw As XmlDictionaryWriter = _
XmlDictionaryWriter.CreateTextWriter(someStream, Encoding.UTF8)
dcs.WriteObject(xdw, p)
Person p = new Person();
DataContractSerializer dcs =
new DataContractSerializer(typeof(Person));
XmlDictionaryWriter xdw =
XmlDictionaryWriter.CreateTextWriter(someStream,Encoding.UTF8 );
dcs.WriteObject(xdw, p);
Viene prodotto un XML simile al seguente.
<Person>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
Serializzazione dettagliata
Utilizzare i metodi WriteStartObject, WriteObjectContent e WriteEndObject rispettivamente per scrivere l'elemento finale, scrivere il contenuto dell'oggetto e chiudere l'elemento wrapper.
Nota: |
---|
Non esistono overload Stream di questi metodi. |
Questa serializzazione dettagliata ha due utilizzi comuni. Nel primo caso, viene utilizzata per inserire contenuto, ad esempio attributi o commenti tra WriteStartObject e WriteObjectContent, come illustrato nell'esempio seguente.
dcs.WriteStartObject(xdw, p)
xdw.WriteAttributeString("serializedBy", "myCode")
dcs.WriteObjectContent(xdw, p)
dcs.WriteEndObject(xdw)
dcs.WriteStartObject(xdw, p);
xdw.WriteAttributeString("serializedBy", "myCode");
dcs.WriteObjectContent(xdw, p);
dcs.WriteEndObject(xdw);
Viene prodotto un XML simile al seguente.
<Person serializedBy="myCode">
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
Nel secondo caso, viene utilizzata per evitare di utilizzare WriteStartObject e WriteEndObject e scrivere l'elemento wrapper personalizzato (o per evitare di scrivere un wrapper), come illustrato nel codice seguente.
xdw.WriteStartElement("MyCustomWrapper")
dcs.WriteObjectContent(xdw, p)
xdw.WriteEndElement()
xdw.WriteStartElement("MyCustomWrapper");
dcs.WriteObjectContent(xdw, p);
xdw.WriteEndElement();
Viene prodotto un XML simile al seguente.
<MyCustomWrapper>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</MyCustomWrapper>
Nota: |
---|
L'utilizzo della serializzazione dettagliata può comportare un XML di schema non valido. |
Deserializzazione
Le informazioni seguenti si applicano a qualsiasi classe che eredita da XmlObjectSerializer, incluse le classi DataContractSerializer e NetDataContractSerializer.
La modalità più elementare per deserializzare un oggetto consiste nel chiamare uno degli overload del metodo ReadObject. Esistono tre overload, rispettivamente per la lettura con un XmlDictionaryReader, un XmlReader o un Stream. Si noti che l'overload Stream crea un XmlDictionaryReader testuale che non è protetto da nessuna quota e deve essere utilizzato solo per leggere dati attendibili.
Si noti inoltre che è necessario eseguire il cast dell'oggetto restituito dal metodo ReadObject sul tipo appropriato.
Nel codice seguente viene creata un'istanza di DataContractSerializer e di XmlDictionaryReader, quindi viene deserializzata un'istanza Person
.
Dim dcs As New DataContractSerializer(GetType(Person))
Dim fs As New FileStream(path, FileMode.Open)
Dim reader As XmlDictionaryReader = _
XmlDictionaryReader.CreateTextReader(fs, New XmlDictionaryReaderQuotas())
Dim p As Person = CType(dcs.ReadObject(reader), Person)
DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
FileStream fs = new FileStream(path, FileMode.Open);
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
Person p = (Person)dcs.ReadObject(reader);
Prima di chiamare il metodo ReadObject, posizionare il lettore XML sull'elemento wrapper o su un nodo non di contenuto che precede l'elemento wrapper. A tale fine, chiamare il metodo Read di XmlReader o la sua derivazione e testare NodeType, come illustrato nel codice seguente.
Dim ser As New DataContractSerializer(GetType(Person), "Customer", "https://www.contoso.com")
Dim fs As New FileStream(path, FileMode.Open)
Dim reader As XmlDictionaryReader = XmlDictionaryReader.CreateTextReader(fs, New XmlDictionaryReaderQuotas())
While reader.Read()
Select Case reader.NodeType
Case XmlNodeType.Element
If ser.IsStartObject(reader) Then
Console.WriteLine("Found the element")
Dim p As Person = CType(ser.ReadObject(reader), Person)
Console.WriteLine("{0} {1}", _
p.Name, p.Address)
End If
Console.WriteLine(reader.Name)
End Select
End While
DataContractSerializer ser = new DataContractSerializer(typeof(Person),
"Customer", @"https://www.contoso.com");
FileStream fs = new FileStream(path, FileMode.Open);
XmlDictionaryReader reader =
XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (ser.IsStartObject(reader))
{
Console.WriteLine("Found the element");
Person p = (Person)ser.ReadObject(reader);
Console.WriteLine("{0} {1} id:{2}",
p.Name , p.Address);
}
Console.WriteLine(reader.Name);
break;
}
}
Si noti che è possibile leggere gli attributi in questo elemento wrapper prima di passare il lettore a ReadObject
.
Quando viene utilizzato uno degli overload ReadObject
semplici, il deserializzatore cerca il nome e lo spazio dei nomi predefiniti nell'elemento wrapper (vedere la sezione precedente, "Specifica del nome principale e dello spazio dei nomi predefiniti") e, se trova un elemento sconosciuto, genera un'eccezione. Nell'esempio precedente è previsto l'elemento wrapper <Person>
. Per verificare che il lettore sia posizionato su un elemento denominato come previsto, viene chiamato il metodo IsStartObject.
Il controllo del nome di un elemento wrapper può essere disattivato. Alcuni overload del metodo ReadObject prendono il parametro booleano verifyObjectName, la cui impostazione predefinita è true. Quando è impostato su false, il nome e lo spazio dei nomi dell'elemento wrapper vengono ignorati. Ciò è utile per leggere l'XML scritto utilizzando il meccanismo di serializzazione dettagliata descritto in precedenza.
Utilizzo di NetDataContractSerializer
La differenza principale tra DataContractSerializer e NetDataContractSerializer è data dal fatto che DataContractSerializer utilizza nomi del contratto dati, mentre NetDataContractSerializer genera nomi di assembly e dei tipi .NET Framework completi nell'XML serializzato. Ciò significa che devono essere condivisi esattamente gli stessi tipi tra gli endpoint di serializzazione e di deserializzazione. Il meccanismo dei tipi conosciuti non è pertanto richiesto con NetDataContractSerializer perché i tipi esatti da deserializzare sono sempre conosciuti.
Possono tuttavia verificarsi numerosi problemi:
Protezione. Viene caricato qualsiasi tipo trovato nell'XML che viene deserializzato. Questo comportamento può essere sfruttato per forzare il caricamento di tipi dannosi. È consigliabile utilizzare NetDataContractSerializer con dati non attendibili solo se viene utilizzato un gestore di associazione della serializzazione (tramite la proprietà Binder o il parametro del costruttore). Il gestore di associazione consente che vengano caricati solo i tipi sicuri. Il meccanismo del gestore di associazione è identico a quello utilizzato dai tipi nello spazio dei nomi System.Runtime.Serialization.
Controllo delle versioni. L'utilizzo di nomi di assembly e di tipo completi nell'XML limita rigidamente il modo in cui è possibile controllare le versioni dei tipi. Non è possibile modificare gli elementi seguenti: nomi dei tipi, spazi dei nomi, nomi degli assembly e versioni degli assembly. L'impostazione della proprietà AssemblyFormat o del parametro del costruttore su Simple anziché sul valore predefinito di Full consente di modificare la versione dell'assembly, fatta eccezione per i tipi di parametro generici.
Interoperabilità. Dato che i nomi degli assembly e dei tipi .NET Framework sono inclusi nell'XML, piattaforme diverse da .NET Framework non possono accedere ai dati risultanti.
Prestazioni. La scrittura dei nomi di tipi e assembly aumenta notevolmente le dimensioni dell'XML risultante.
Questo meccanismo è simile alla serializzazione SOAP o binaria utilizzata da .NET Framework Remoting (nello specifico, BinaryFormatter e SoapFormatter).
L'utilizzo di NetDataContractSerializer è simile a quello di DataContractSerializer, tranne che per le differenze seguenti:
I costruttori non richiedono che venga specificato un tipo radice. È possibile serializzare qualsiasi tipo con la stessa istanza di NetDataContractSerializer.
I costruttori non accettano un elenco di tipi conosciuti. Il meccanismo dei tipi conosciuti è non necessario se i nomi dei tipi sono serializzati nell'XML.
I costruttori non accettano un surrogato del contratto dati. Accettano invece un parametro ISurrogateSelector chiamato surrogateSelector (che esegue il mapping alla proprietà SurrogateSelector). Si tratta di un meccanismo surrogato legacy.
Il costruttore accetta un parametro chiamato assemblyFormat di FormatterAssemblyStyle che esegue il mapping alla proprietà AssemblyFormat. Come illustrato in precedenza, ciò può essere utilizzato per migliorare le funzionalità di controllo delle versioni del serializzatore. È identico al meccanismo FormatterAssemblyStyle nella serializzazione SOAP o binaria.
Il costruttore accetta un parametro StreamingContext chiamato context che esegue il mapping alla proprietà Context. È possibile utilizzare questa funzionalità per passare informazioni nei tipi serializzati. Questo utilizzo è identico a quello del meccanismo StreamingContext utilizzato in altre classi System.Runtime.Serialization.
I metodi Serialize e Deserialize sono alias per i metodi WriteObject e ReadObject. Hanno la funzione di fornire un modello di programmazione più coerente con la serializzazione SOAP o binaria.
Per ulteriori informazioni su queste funzionalità, vedere Binary Serialization.
I formati XML utilizzati da NetDataContractSerializer e DataContractSerializer in genere non sono compatibili. Ciò significa che non è consentito eseguire la serializzazione con uno di questi serializzatori e la deserializzazione con l'altro.
Si noti inoltre che NetDataContractSerializer non restituisce il nome dell'assembly e del tipo completo .NET Framework per ogni nodo nell'oggetto grafico. Restituisce queste informazioni solo in caso di ambiguità. Ovvero, a livello dell'oggetto radice e per il qualsiasi caso polimorfico.
Vedere anche
Riferimento
DataContractSerializer
NetDataContractSerializer
XmlObjectSerializer
Concetti
Tipi supportati dal serializzatore dei contratti dati