Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Windows Communication Foundation (WCF) include un nuovo motore di serializzazione, ovvero DataContractSerializer. DataContractSerializer traduce tra oggetti .NET Framework e XML, in entrambe le direzioni. In questo argomento viene illustrato il funzionamento del serializzatore.
Quando si serializzano oggetti .NET Framework, il serializzatore comprende un'ampia gamma di modelli di programmazione di serializzazione, incluso il nuovo modello di contratto dati . Per un elenco completo dei tipi supportati, vedere Tipi supportati dal serializzatore di contratti dati. Per un'introduzione ai contratti dati, vedere Uso dei contratti dati.
Durante la deserializzazione di XML, il serializzatore utilizza le XmlReader classi e XmlWriter . Supporta inoltre le XmlDictionaryReader classi e XmlDictionaryWriter per abilitarla per produrre codice XML ottimizzato in alcuni casi, ad esempio quando si usa il formato XML binario WCF.
WCF include anche un serializzatore complementare, ovvero NetDataContractSerializer. NetDataContractSerializer:
- Non è sicuro. Per altre informazioni, vedere la guida alla sicurezza BinaryFormatter.
- È simile ai serializzatori BinaryFormatter e SoapFormatter perché emette anch'esso i nomi dei tipi del .NET Framework come parte dei dati serializzati.
- Viene utilizzato quando gli stessi tipi sono condivisi sia in fase di serializzazione che di deserializzazione.
Sia DataContractSerializer che NetDataContractSerializer derivano da una classe base comune, XmlObjectSerializer.
Avvertimento
DataContractSerializer Serializza stringhe contenenti caratteri di controllo con un valore esadecimale inferiore a 20 come entità XML. Ciò può causare un problema con un client non WCF quando si inviano tali dati a un servizio WCF.
Creazione di un'istanza di DataContractSerializer
La creazione di un'istanza di DataContractSerializer è un passaggio importante. Dopo la costruzione, non è possibile modificare alcuna delle impostazioni.
Specificazione del tipo radice
Il tipo radice è il tipo di istanze serializzate o deserializzate. Il DataContractSerializer ha molti overload del costruttore, ma, almeno, un tipo radice deve essere fornito usando il parametro type
.
Un serializzatore creato per un determinato 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 seguente vengono illustrate due classi.
[DataContract]
public class Person
{
// Code not shown.
}
[DataContract]
public class PurchaseOrder
{
// Code not shown.
}
<DataContract()> _
Public Class Person
' Code not shown.
End Class
<DataContract()> _
Public Class PurchaseOrder
' Code not shown.
End Class
Questo codice costruisce un'istanza DataContractSerializer
di che può essere utilizzata solo per serializzare o deserializzare istanze della Person
classe .
DataContractSerializer dcs = new DataContractSerializer(typeof(Person));
// This can now be used to serialize/deserialize Person but not PurchaseOrder.
Dim dcs As New DataContractSerializer(GetType(Person))
' This can now be used to serialize/deserialize Person but not PurchaseOrder.
Specifica di tipi noti
Se il polimorfismo è coinvolto nei tipi serializzati che non sono già gestiti utilizzando l'attributo KnownTypeAttribute o un altro meccanismo, è necessario passare un elenco di possibili tipi noti al costruttore del serializzatore usando il knownTypes
parametro . Per altre informazioni sui tipi noti, vedere Tipi noti del contratto dati.
Nell'esempio seguente viene illustrata una classe , LibraryPatron
, che include una raccolta di un tipo specifico, ovvero LibraryItem
. La seconda classe definisce il LibraryItem
tipo. La terza e quattro classi (Book
e Newspaper
) ereditano dalla LibraryItem
classe .
[DataContract]
public class LibraryPatron
{
[DataMember]
public LibraryItem[] borrowedItems;
}
[DataContract]
public class LibraryItem
{
// Code not shown.
}
[DataContract]
public class Book : LibraryItem
{
// Code not shown.
}
[DataContract]
public class Newspaper : LibraryItem
{
// Code not shown.
}
<DataContract()> _
Public Class LibraryPatron
<DataMember()> _
Public borrowedItems() As LibraryItem
End Class
<DataContract()> _
Public Class LibraryItem
' Code not shown.
End Class
<DataContract()> _
Public Class Book
Inherits LibraryItem
' Code not shown.
End Class
<DataContract()> _
Public Class Newspaper
Inherits LibraryItem
' Code not shown.
End Class
Il codice seguente costruisce un'istanza del serializzatore usando il knownTypes
parametro .
// 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.
' 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.
Specificare il nome radice predefinito e lo spazio dei nomi
In genere, quando un oggetto viene serializzato, il nome predefinito e lo spazio dei nomi dell'elemento XML più esterno vengono determinati in base al nome e allo spazio dei nomi del contratto dati. I nomi di tutti gli elementi interni vengono determinati dai nomi dei membri dei dati e il loro spazio dei nomi è lo spazio dei nomi di contratto di dati. Nell'esempio seguente, i valori Name
e Namespace
vengono impostati nei costruttori delle classi DataContractAttribute e DataMemberAttribute.
[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;
}
<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
La serializzazione di un'istanza della Person
classe produce codice XML simile al seguente.
<PersonContract xmlns="http://schemas.contoso.com">
<AddressMember>
<StreetMember>123 Main Street</StreetMember>
</AddressMember>
</PersonContract>
Tuttavia, è possibile personalizzare il nome predefinito e lo spazio dei nomi dell'elemento radice passando i valori dei rootName
parametri e rootNamespace
al DataContractSerializer costruttore. 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 istanze della XmlDictionaryString classe per consentire l'ottimizzazione usando il formato XML binario.
Impostazione della quota massima di oggetti
Alcuni sovraccarichi DataContractSerializer
del costruttore hanno un parametro maxItemsInObjectGraph
. Questo parametro determina il numero massimo di oggetti che il serializzatore serializza o deserializza in una singola ReadObject chiamata al metodo. Il metodo legge sempre un oggetto radice, ma questo oggetto può avere altri oggetti nei relativi membri dati. Tali oggetti possono avere altri oggetti e così via. Il valore predefinito è 65536. Si noti che durante la serializzazione o la deserializzazione di matrici, ogni voce di matrice viene conteggiato come oggetto separato. Si noti inoltre che alcuni oggetti possono avere una rappresentazione di memoria di grandi dimensioni e pertanto questa quota da sola potrebbe non essere sufficiente per impedire un attacco Denial of Service. Per altre informazioni, vedere Considerazioni sulla sicurezza per i dati. Se è necessario aumentare questa quota oltre il valore predefinito, è importante farlo sia sul lato invio (serializzazione) che sulla ricezione (deserializzazione) perché si applica sia alla lettura che alla scrittura dei dati.
Viaggi di andata e ritorno
Un round trip si verifica quando un oggetto viene deserializzato e serializzato nuovamente in un'unica operazione. Di conseguenza, passa da XML a un'istanza di oggetto e torna in un flusso XML.
Alcuni DataContractSerializer
sovraccarichi del costruttore hanno un parametro ignoreExtensionDataObject
, che è impostato su false
per impostazione predefinita. In questa modalità predefinita, i dati possono essere inviati in un round trip da una versione più recente di un contratto dati tramite una versione precedente e tornare alla versione più recente senza perdita, purché 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 Name
aggiunga un membro . Se IExtensibleDataObject
viene implementato, quando si inviano informazioni dalla versione 2 alla versione 1, i Nickname
dati vengono archiviati e quindi nuovamente generati quando i dati vengono serializzati nuovamente, pertanto non vengono persi dati nel round trip. Per altre informazioni, vedere Forward-Compatible Contratti di Dati e Versioning del Contratto Dati.
Problemi di sicurezza e validità dello schema con round trip
I round trip possono avere implicazioni per la sicurezza. Ad esempio, la deserializzazione e l'archiviazione di grandi quantità di dati estranei possono essere un rischio per la sicurezza. Potrebbero esserci problemi di sicurezza relativi alla ricreazione di questi dati che non è possibile verificare, soprattutto se sono coinvolte firme digitali. Ad esempio, nello scenario precedente, l'endpoint della versione 1 potrebbe firmare un Nickname
valore che contiene dati dannosi. Infine, potrebbero esserci problemi di validità dello schema: un endpoint può voler sempre generare dati che rispettano rigorosamente il contratto dichiarato e non alcun valore aggiuntivo. Nell'esempio precedente il contratto dell'endpoint versione 1 indica che genera solo Name
e PhoneNumber
e se viene usata la convalida dello schema, l'emissione del valore aggiuntivo Nickname
causa l'esito negativo della convalida.
Abilitazione e disabilitazione dei viaggi di andata e ritorno
Per disattivare il round trip, non implementare l'interfaccia IExtensibleDataObject. Se non si ha alcun controllo sui tipi, impostare il ignoreExtensionDataObject
parametro su true
per ottenere lo stesso effetto.
Conservazione dell'oggetto grafico
In genere, il serializzatore non si preoccupa dell'identità dell'oggetto, come nel codice seguente.
[DataContract]
public class PurchaseOrder
{
[DataMember]
public Address billTo;
[DataMember]
public Address shipTo;
}
[DataContract]
public class Address
{
[DataMember]
public string street;
}
<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
Il codice seguente crea un ordine di acquisto.
// Construct a purchase order:
Address adr = new Address();
adr.street = "123 Main St.";
PurchaseOrder po = new PurchaseOrder();
po.billTo = adr;
po.shipTo = adr;
' 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
Si noti che i campi billTo
e shipTo
vengono impostati sulla stessa istanza dell'oggetto. Tuttavia, il codice XML generato duplica le informazioni duplicate e ha un aspetto simile al codice XML seguente.
<PurchaseOrder>
<billTo><street>123 Main St.</street></billTo>
<shipTo><street>123 Main St.</street></shipTo>
</PurchaseOrder>
Tuttavia, questo approccio presenta le caratteristiche seguenti, che possono essere indesiderate:
Prestazione. La replica dei dati non è efficiente.
Riferimenti circolari. Se gli oggetti si riferiscono a se stessi, anche tramite altri oggetti, la serializzazione in base alla replica comporta un ciclo infinito. Il serializzatore genera un'eccezione SerializationException in questo caso.
Semantica. A volte è importante mantenere il fatto che due riferimenti siano allo stesso oggetto e non a due oggetti identici.
Per questi motivi, alcuni sovraccarichi del costruttore hanno un parametro DataContractSerializer
(dove il valore predefinito è preserveObjectReferences
). Quando questo parametro è impostato su true
, viene usato un metodo speciale di riferimento all'oggetto di codifica, che riconosce solo WCF. Se impostato su true
, l'esempio di codice XML è ora 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" fa riferimento allo spazio dei nomi di serializzazione standard, http://schemas.microsoft.com/2003/10/Serialization/
. Ogni parte di dati viene serializzata una sola volta e viene assegnato un numero ID e gli usi successivi generano un riferimento ai dati già serializzati.
Importante
Se entrambi gli attributi "id" e "ref" sono presenti nel contratto XMLElement
dati , l'attributo "ref" viene rispettato e l'attributo "id" viene ignorato.
È importante comprendere le limitazioni di questa modalità:
Il codice XML prodotto
DataContractSerializer
conpreserveObjectReferences
impostato sutrue
non è interoperabile con altre tecnologie e può essere accessibile solo da un'altraDataContractSerializer
istanza, anche conpreserveObjectReferences
impostato sutrue
.Non è disponibile alcun supporto di metadati (schema) per questa funzionalità. Lo schema prodotto è valido solo per il caso in cui
preserveObjectReferences
è impostato sufalse
.Questa funzionalità può causare un rallentamento del processo di serializzazione e deserializzazione. Anche se i dati non devono essere replicati, è necessario eseguire confronti di oggetti aggiuntivi in questa modalità.
Attenzione
Quando la preserveObjectReferences
modalità è abilitata, è particolarmente importante impostare il maxItemsInObjectGraph
valore sulla quota corretta. A causa del modo in cui le matrici vengono gestite in questa modalità, è facile per un utente malintenzionato creare un piccolo messaggio dannoso che comporta un consumo elevato di memoria limitato solo dalla maxItemsInObjectGraph
quota.
Specificazione di un surrogato di contratto di dati
Alcuni DataContractSerializer
sovraccarichi del costruttore hanno un dataContractSurrogate
parametro, che può essere impostato su null
. In caso contrario, è possibile usarlo per specificare un surrogato del contratto dati, ovvero un tipo che implementa l'interfaccia IDataContractSurrogate . È quindi possibile usare l'interfaccia per personalizzare il processo di serializzazione e deserializzazione. Per altre informazioni, vedere Sostituti del contratto di dati.
Serializzazione
Le informazioni seguenti si applicano a qualsiasi classe che eredita da XmlObjectSerializer, incluse le DataContractSerializer classi e NetDataContractSerializer .
Serializzazione semplice
Il modo più semplice per serializzare un oggetto consiste nel passarlo al WriteObject metodo . Sono disponibili tre overload, uno per la scrittura in un Stream oggetto, un XmlWriter oggetto o un XmlDictionaryWriter oggetto. Con il sovraccarico, l'output è Stream XML nella codifica UTF-8. Con l'overload XmlDictionaryWriter, il serializzatore ottimizza il suo output per il formato XML binario.
Quando si utilizza il metodo WriteObject, il serializzatore usa il nome e lo spazio dei nomi predefiniti per l'elemento wrapper e lo elabora insieme al contenuto (vedere la sezione precedente "Specifica del nome radice predefinito e dello spazio dei nomi").
Nell'esempio seguente viene mostrato come scrivere con un oggetto XmlDictionaryWriter.
Person p = new Person();
DataContractSerializer dcs =
new DataContractSerializer(typeof(Person));
XmlDictionaryWriter xdw =
XmlDictionaryWriter.CreateTextWriter(someStream,Encoding.UTF8 );
dcs.WriteObject(xdw, p);
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)
In questo modo viene generato codice XML simile al seguente.
<Person>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
PassaggioBy-Step di serializzazione
Usare i metodi WriteStartObject, WriteObjectContent e WriteEndObject per scrivere l'elemento finale, scrivere il contenuto dell'oggetto e chiudere rispettivamente l'elemento wrapper.
Nota
Non esistono sovraccarichi di questi metodi.
Questa serializzazione dettagliata include due usi comuni. Uno consiste nell'inserire contenuti come 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)
In questo modo viene generato codice XML simile al seguente.
<Person serializedBy="myCode">
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
Un altro uso comune consiste nell'evitare di usare WriteStartObject e WriteEndObject completamente e scrivere un elemento wrapper personalizzato (o anche ignorare completamente la scrittura di 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()
In questo modo viene generato codice XML simile al seguente.
<MyCustomWrapper>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</MyCustomWrapper>
Nota
L'uso della serializzazione sequenziale può comportare XML non valido per lo schema.
Deserializzazione
Le informazioni seguenti si applicano a qualsiasi classe che eredita da XmlObjectSerializer, incluse le DataContractSerializer classi e NetDataContractSerializer .
Il modo più semplice per deserializzare un oggetto consiste nel chiamare uno degli overload del ReadObject metodo. Sono disponibili tre overload, uno per la lettura con un XmlDictionaryReader, un XmlReader
, o un Stream
. Si noti che l'overload Stream
crea un elemento testuale XmlDictionaryReader che non è protetto da alcuna quota e dovrebbe essere usato solo per leggere dati di cui ci si fida.
Si noti anche che l'oggetto restituito dal metodo ReadObject
deve essere effettuato il cast al tipo appropriato.
Il codice seguente costruisce un'istanza di DataContractSerializer e un'istanza di XmlDictionaryReader, quindi deserializza un'istanza di 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);
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)
Prima di chiamare il ReadObject metodo , posizionare il lettore XML sull'elemento wrapper o su un nodo non di contenuto che precede l'elemento wrapper. A tale scopo, è possibile chiamare il metodo Read di XmlReader o della sua derivazione, e testare NodeType, come mostrato nel codice seguente.
DataContractSerializer ser = new DataContractSerializer(typeof(Person),
"Customer", @"http://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($"{p.Name} {p.Address} id:{2}");
}
Console.WriteLine(reader.Name);
break;
}
}
Dim ser As New DataContractSerializer(GetType(Person), "Customer", "http://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
Si noti che è possibile leggere gli attributi su questo elemento wrapper prima di passare il lettore a ReadObject
.
Quando si usa uno degli overload semplici ReadObject
, il deserializzatore cerca il nome e gli spazi dei nomi predefiniti nell'elemento wrapper (vedere la sezione precedente, "Impostare il nome radice e lo spazio dei nomi predefiniti") e solleva un'eccezione se trova un elemento sconosciuto. Nell'esempio precedente è previsto l'elemento <Person>
wrapper. Viene chiamato il IsStartObject metodo per verificare che il lettore sia posizionato su un elemento denominato come previsto.
C'è un modo per disabilitare questo controllo del nome dell'elemento wrapper; alcuni overload del metodo ReadObject
accettano il parametro booleano verifyObjectName
, che è impostato su true
per impostazione predefinita. Se impostato su false
, il nome e lo spazio dei nomi dell'elemento wrapper vengono ignorati. Ciò è utile per la lettura del codice XML scritto usando il meccanismo di serializzazione dettagliato descritto in precedenza.
Uso di NetDataContractSerializer
La differenza principale tra DataContractSerializer
e NetDataContractSerializer è che DataContractSerializer
usa nomi di contratto dati, mentre NetDataContractSerializer
restituisce nomi completi di assembly .NET Framework e di tipo nel XML serializzato. Ciò significa che gli stessi tipi devono essere condivisi tra gli endpoint di serializzazione e deserializzazione. Ciò significa che il meccanismo dei tipi noti non è necessario con NetDataContractSerializer
perché i tipi esatti da deserializzare sono sempre noti.
Tuttavia, possono verificarsi diversi problemi:
Sicurezza. Viene caricato qualsiasi tipo trovato nell'XML in fase di deserializzazione. Questo può essere sfruttato per forzare il caricamento di tipi dannosi. L'uso di
NetDataContractSerializer
con dati non attendibili deve essere eseguito solo se viene usato un binder di serializzazione (usando la proprietà o il parametro del Binder costruttore). Il binder consente di caricare solo tipi sicuri. Il meccanismo Binder è identico a quello usato dai tipi nello spazio dei nomi System.Runtime.Serialization.Controllo delle versioni. L'uso di nomi completi di tipi e assembly nel codice XML limita notevolmente la modalità di controllo delle versioni dei tipi. Non è possibile modificare i nomi dei tipi, gli spazi dei nomi, i nomi degli assembly e le versioni degli assembly. L'impostazione del parametro della proprietà o del costruttore su AssemblyFormat anziché sul valore predefinito di Simple consente di modificare la versione dell'assembly, ma non per i tipi di parametri generici.
Interoperabilità. Poiché i nomi di assembly e di tipo .NET Framework sono inclusi nel codice XML, le piattaforme diverse da .NET Framework non possono accedere ai dati risultanti.
Prestazione. La scrittura dei nomi di tipo e assembly aumenta significativamente le dimensioni del codice XML risultante.
Questo meccanismo è simile alla serializzazione binaria o SOAP usata dalla comunicazione remota di .NET Framework (in particolare, BinaryFormatter e SoapFormatter).
L'uso NetDataContractSerializer
di è simile all'uso di DataContractSerializer
, con le differenze seguenti:
I costruttori non richiedono di specificare un tipo di elemento radice. È possibile serializzare qualsiasi tipo con la stessa istanza di
NetDataContractSerializer
.I costruttori non accettano un elenco di tipi noti. Il meccanismo dei tipi noti non è necessario se i nomi dei tipi vengono serializzati nel codice XML.
I costruttori non accettano un surrogato del contratto di dati. Accettano invece un ISurrogateSelector parametro, denominato
surrogateSelector
, che si mappa alla proprietà SurrogateSelector. Si tratta di un meccanismo surrogato legacy.I costruttori accettano un parametro denominato
assemblyFormat
dell'oggetto FormatterAssemblyStyle che mappa alla proprietà AssemblyFormat. Come illustrato in precedenza, questo può essere usato per migliorare le funzionalità di controllo delle versioni del serializzatore. Questo è identico al FormatterAssemblyStyle meccanismo nella serializzazione binaria o SOAP.I costruttori accettano un parametro StreamingContext chiamato
context
che viene mappato sulla proprietà Context. È possibile usarlo per passare informazioni ai tipi da serializzare. Questo utilizzo è identico a quello del StreamingContext meccanismo usato in altre System.Runtime.Serialization classi.I Serialize metodi e Deserialize sono alias per i WriteObject metodi e ReadObject . Esistono per fornire un modello di programmazione più coerente con serializzazione binaria o SOAP.
Per altre informazioni su queste funzionalità, vedere Serializzazione binaria.
I formati XML che NetDataContractSerializer
e DataContractSerializer
utilizzano non sono normalmente compatibili. Ovvero, il tentativo di serializzare con uno di questi serializzatori e deserializzare con l'altro non è uno scenario supportato.
Si noti inoltre che NetDataContractSerializer
non restituisce il tipo completo di .NET Framework e il nome dell'assembly per ogni nodo nell'oggetto grafico. Restituisce tali informazioni solo dove è ambiguo. Ovvero, produce risultati a livello di oggetto radice e per eventuali casi polimorfici.