Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Windows Communication Foundation (WCF) obsahuje nový serializační modul, DataContractSerializer. DataContractSerializer se překládá mezi objekty rozhraní .NET Framework a XML v obou směrech. Toto téma vysvětluje, jak serializátor funguje.
Při serializaci objektů rozhraní .NET Framework serializátor rozumí nejrůznějším programovacím modelům serializace, včetně nového datového kontraktu modelu. Úplný seznam podporovaných typů naleznete v tématu Typy podporované serializátorem kontraktů dat. Úvod k datovým kontraktům najdete v tématu Použití kontraktů dat.
Při deserializaci XML serializátor používá XmlReader a XmlWriter třídy. Podporuje také třídy XmlDictionaryReader a XmlDictionaryWriter, aby bylo možné v některých případech vytvářet optimalizované XML, například při použití binárního formátu XML WCF.
WCF také obsahuje doprovodný serializátor, NetDataContractSerializer. NetDataContractSerializer:
- Není bezpečný. Další informace naleznete v příručce zabezpečení BinaryFormatter.
- Podobá se BinaryFormatter a SoapFormatter serializátorům, protože také generuje názvy typů rozhraní .NET Framework jako součást serializovaných dat.
- Používá se, pokud jsou stejné typy sdíleny na serializaci a deserializace končí.
DataContractSerializer i NetDataContractSerializer jsou odvozeny od společné základní třídy XmlObjectSerializer.
Varování
DataContractSerializer serializuje řetězce obsahující řídicí znaky s hexadecimální hodnotou nižší než 20 jako entit XML. To může způsobit problém s jiným klientem než WCF při odesílání těchto dat do služby WCF.
Vytvoření instance DataContractSerializer
Vytvoření instance DataContractSerializer je důležitým krokem. Po konstrukci nemůžete změnit žádné nastavení.
Zadání kořenového typu
kořenový typ je typ, jehož instance jsou serializovány nebo deserializovány.
DataContractSerializer má mnoho přetížení konstruktoru, ale alespoň kořenový typ musí být zadán pomocí parametru type.
Serializátor vytvořený pro určitý kořenový typ nelze použít k serializaci (nebo deserializaci) jiného typu, pokud typ není odvozen od kořenového typu. Následující příklad ukazuje dvě třídy.
[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
Tento kód vytvoří instanci DataContractSerializer, která lze použít pouze k serializaci nebo deserializaci instancí Person třídy.
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.
Určení známých typů
Pokud se polymorfismus podílí na serializovaných typech, které ještě nejsou zpracovávány pomocí atributu KnownTypeAttribute nebo jiného mechanismu, musí být seznam možných známých typů předán konstruktoru serializátoru pomocí knownTypes parametru. Další informace o známých typech naleznete v tématu Data Contract Známé typy.
Následující příklad ukazuje třídu, LibraryPatron, která obsahuje kolekci určitého typu, LibraryItem. Druhá třída definuje typ LibraryItem. Třetí a čtyři třídy (Book a Newspaper) dědí z třídy LibraryItem.
[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
Následující kód vytvoří instanci serializátoru pomocí knownTypes parametru.
// 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.
Zadání výchozího kořenového názvu a oboru názvů
Při serializaci objektu se obvykle určuje výchozí název a obor názvů vnějšího elementu XML podle názvu datového kontraktu a oboru názvů. Názvy všech vnitřních prvků jsou určeny z názvů datových členů a jejich obor názvů odpovídá oboru názvů datového kontraktu. Následující příklad nastaví hodnoty Name a Namespace v konstruktorech tříd DataContractAttribute a 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
Serializace instance Person třídy vytvoří XML podobný následujícímu.
<PersonContract xmlns="http://schemas.contoso.com">
<AddressMember>
<StreetMember>123 Main Street</StreetMember>
</AddressMember>
</PersonContract>
Výchozí název a obor názvů kořenového prvku však můžete přizpůsobit předáním hodnot parametrů rootName a rootNamespace konstruktoru DataContractSerializer. Všimněte si, že rootNamespace nemá vliv na obor názvů obsažených prvků, které odpovídají datovým členům. Ovlivňuje pouze obor názvů vnějšího prvku.
Tyto hodnoty lze předat jako řetězce nebo instance XmlDictionaryString třídy, aby bylo možné jejich optimalizaci pomocí binárního formátu XML.
Nastavení maximální kvóty objektů
Některá přetížení konstruktoru DataContractSerializer mají parametr maxItemsInObjectGraph. Tento parametr určuje maximální počet objektů, které serializátor serializuje nebo deserializuje během jediného volání metody ReadObject. (Metoda vždy čte jeden kořenový objekt, ale tento objekt může mít jiné objekty ve svých datových členech. Tyto objekty mohou mít jiné objekty atd.) Výchozí hodnota je 65536. Všimněte si, že při serializaci nebo deserializaci polí se každá položka pole počítá jako samostatný objekt. Všimněte si také, že některé objekty můžou mít velkou reprezentaci paměti, a proto samotná kvóta nemusí být dostatečná, aby se zabránilo útoku na dostupnost služby. Pro více informací, viz Bezpečnostní úvahy týkající se dat. Pokud potřebujete tuto kvótu zvýšit nad výchozí hodnotu, je důležité to udělat jak na straně odesílání (serializace), tak na straně příjmu (deserializace), protože platí pro čtení i zápis dat.
Zpáteční cesty
cyklus nastane, když je objekt deserializován a znovu serializován v jedné operaci. Proto jde z XML na instanci objektu a zpět do datového proudu XML.
Některá přetížení konstruktoru DataContractSerializer mají parametr ignoreExtensionDataObject, který je ve výchozím nastavení nastavený na false. V tomto výchozím režimu je možné odesílat data na zpáteční cestu z novější verze kontraktu dat prostřednictvím starší verze a zpět na novější verzi bez ztráty, pokud kontrakt dat implementuje rozhraní IExtensibleDataObject. Předpokládejme například, že verze 1 Person datového kontraktu obsahuje Name a PhoneNumber datové členy a verze 2 přidá Nickname člena. Pokud se IExtensibleDataObject implementuje, při odesílání informací z verze 2 do verze 1 se uloží data Nickname a se znovu emitují při opětovné serializaci dat; proto se při této operaci neztratí žádná data. Další informace najdete v tématu Forward-Compatible datové kontrakty a verzování datových kontraktů.
Obavy o zabezpečení a platnost schématu při zpětných cestách
Zpáteční cesty můžou mít bezpečnostní dopady. Příkladem může být deserializace a ukládání velkých objemů nadbytečných dat bezpečnostní riziko. Mohou existovat bezpečnostní obavy ohledně znovu vydávání těchto dat, pro které neexistuje způsob ověření, zejména pokud jsou do procesu zapojeny digitální podpisy. Například v předchozím scénáři by koncový bod verze 1 mohl podepisovat Nickname hodnotu, která obsahuje škodlivá data. A konečně může docházet k obavám ohledně platnosti schématu: Koncový bod může vždy generovat data, která striktně dodržuje jeho stavový kontrakt, a ne žádné dodatečné hodnoty. V předchozím příkladu kontrakt koncového bodu verze 1 říká, že generuje pouze Name a PhoneNumbera pokud se používá ověřování schématu, generování dodatečné hodnoty Nickname způsobí selhání ověření.
Povolení a zakázání kruhů
Pokud chcete vypnout cykly, neimplementujte rozhraní IExtensibleDataObject. Pokud nemáte žádnou kontrolu nad typy, nastavte parametr ignoreExtensionDataObject na true, abyste dosáhli stejného efektu.
Zachování grafu objektů
Serializátor obvykle nezajímá identitu objektu, jako v následujícím kódu.
[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
Následující kód vytvoří nákupní objednávku.
// 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
Všimněte si, že pole billTo a shipTo jsou nastavená na stejnou instanci objektu. Vygenerovaný KÓD XML však duplikuje informace duplikované a vypadá podobně jako následující XML.
<PurchaseOrder>
<billTo><street>123 Main St.</street></billTo>
<shipTo><street>123 Main St.</street></shipTo>
</PurchaseOrder>
Tento přístup má však následující charakteristiky, které mohou být nežádoucí:
Výkon. Replikace dat je neefektivní.
Cyklické odkazy. Pokud se objekty odkazují na sebe, i přes jiné objekty, serializace replikací vede k nekonečné smyčce. (Pokud k tomu dojde, serializátor vyvolá chybu SerializationException.)
Sémantika. Někdy je důležité zachovat skutečnost, že dva odkazy jsou na stejný objekt, a ne na dva identické objekty.
Z těchto důvodů mají některá přetížení DataContractSerializer konstruktoru parametr preserveObjectReferences (výchozí hodnota je false). Pokud je tento parametr nastaven na true, je použita speciální metoda kódování odkazů na objekty, která pouze WCF rozumí. Při nastavení na trueteď příklad kódu XML vypadá podobně jako následující.
<PurchaseOrder ser:id="1">
<billTo ser:id="2"><street ser:id="3">123 Main St.</street></billTo>
<shipTo ser:ref="2"/>
</PurchaseOrder>
Prostor názvů "ser" odkazuje na standardní prostor pro serializaci, http://schemas.microsoft.com/2003/10/Serialization/. Každá část dat je serializována pouze jednou a zadanou číslem ID a následná použití vede k odkazu na již serializovaná data.
Důležité
Pokud jsou v XMLElementkontraktu dat přítomny atributy "id" a "ref", je atribut "ref" dodržen a "id" atribut je ignorován.
Je důležité pochopit omezení tohoto režimu:
XML, který
DataContractSerializervytvoří při nastavenípreserveObjectReferencesnatrue, není interoperabilní s žádnými dalšími technologiemi a lze k němu přistupovat pouze pomocí jiné instanceDataContractSerializer, rovněž spreserveObjectReferencesnastavené natrue.Pro tuto funkci není podporována žádná metadata (schéma). Schéma vytvořené je platné pouze pro případ, kdy je
preserveObjectReferencesnastavena nafalse.Tato funkce může způsobit pomalejší proces serializace a deserializace. I když data nemusí být replikována, musí se v tomto režimu provádět další porovnání objektů.
Upozornění
Pokud je režim preserveObjectReferences povolený, je zvlášť důležité nastavit maxItemsInObjectGraph hodnotu na správnou kvótu. Vzhledem ke způsobu zpracování polí v tomto režimu je pro útočníka snadné vytvořit malou škodlivou zprávu, která vede k velké spotřebě paměti omezené pouze kvótou maxItemsInObjectGraph.
Určení náhradníka datového kontraktu
Některá přetížení konstruktoru DataContractSerializer mohou mít parametr dataContractSurrogate, který může být nastaven na null. V opačném případě jej můžete použít k určení náhradníhodatového kontraktu , což je typ, který implementuje IDataContractSurrogate rozhraní. Rozhraní pak můžete použít k přizpůsobení serializace a deserializace procesu. Další informace viz Zástupci datových smluv.
Serializace
Následující informace platí pro všechny třídy, které dědí z XmlObjectSerializer, včetně tříd DataContractSerializer a NetDataContractSerializer.
Jednoduchá serializace
Nejzásadnější způsob serializace objektu je předat ho WriteObject metodě. Existují tři přetížení, každé pro zápis do Stream, XmlWriternebo XmlDictionaryWriter. Při přetížení Stream je výstup XML v kódování UTF-8. S přetížením XmlDictionaryWriter serializátor optimalizuje svůj výstup pro binární XML.
Při použití WriteObject metoda serializátor použije výchozí název a obor názvů pro element obálky a zapíše ho spolu s obsahem (viz předchozí část Zadání výchozího kořenového názvu a oboru názvů).
Následující příklad ukazuje psaní s prvkem 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)
Tím se vytvoří kód XML podobný následujícímu.
<Person>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
Krok – serializaceBy-Step
Metody WriteStartObject, WriteObjectContenta WriteEndObject k zápisu koncového prvku, zápisu obsahu objektu a zavření elementu obálky.
Poznámka:
Neexistují žádné Stream přetížení těchto metod.
Tato podrobná serializace má dvě společná použití. Jedním z nich je vložit obsah, jako jsou atributy nebo komentáře mezi WriteStartObject a WriteObjectContent, jak je znázorněno v následujícím příkladu.
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)
Tím se vytvoří kód XML podobný následujícímu.
<Person serializedBy="myCode">
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
Dalším běžným použitím je zcela se vyhnout použití WriteStartObject a WriteEndObject a napsat vlastní obalový prvek (nebo dokonce úplně vynechat psaní obalu), jak je znázorněno v kódu níže.
xdw.WriteStartElement("MyCustomWrapper");
dcs.WriteObjectContent(xdw, p);
xdw.WriteEndElement();
xdw.WriteStartElement("MyCustomWrapper")
dcs.WriteObjectContent(xdw, p)
xdw.WriteEndElement()
Tím se vytvoří kód XML podobný následujícímu.
<MyCustomWrapper>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</MyCustomWrapper>
Poznámka:
Při použití podrobné serializace může dojít k neplatnému schématu XML.
Deserializace
Následující informace platí pro všechny třídy, které dědí z XmlObjectSerializer, včetně tříd DataContractSerializer a NetDataContractSerializer.
Nejzásadnější způsob deserializace objektu je volání jednoho z přetížení metody ReadObject. Existují tři přetížení, jedno každé pro čtení s XmlDictionaryReader, XmlReader, nebo Stream. Všimněte si, že přetížení Stream vytvoří textovou XmlDictionaryReader, která není chráněna žádnými kvótami, a měla by být použita pouze ke čtení důvěryhodných dat.
Všimněte si také, že objekt, který ReadObject metoda vrací, musí být přetypován na příslušný typ.
Následující kód vytvoří instanci DataContractSerializer a XmlDictionaryReadera pak deserializuje instanci 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)
Před voláním metody ReadObject umístěte čtečku XML na element obálky nebo na uzel bez obsahu, který předchází elementu obálky. Můžete to provést voláním metody Read u XmlReader nebo její odvozeniny a otestováním NodeType, jak je znázorněno v následujícím kódu.
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
Všimněte si, že před předáním čtečky na ReadObjectmůžete číst atributy na tomto obalovém prvku.
Při použití některého z jednoduchých přetížení ReadObject deserializer hledá výchozí název a obor názvů v obalovacím prvku (viz předchozí část "Určení výchozího kořenového názvu a oboru názvů") a vyvolá výjimku, pokud najde neznámý prvek. V předchozím příkladu se očekává prvek obálky <Person>. Metoda IsStartObject je volána k ověření, zda je čtenář umístěn na elementu, který je pojmenován očekávaným způsobem.
Je možné vypnout kontrolu názvu tohoto elementu obálky; některé přetížení metody ReadObject přijímají logický parametr verifyObjectName, který je ve výchozím nastavení nastaven na true. Při nastavení na falsese název a obor názvů obálkového elementu ignoruje. To je užitečné pro čtení XML, který byl napsán pomocí podrobného serializačního mechanismu popsaného dříve.
Použití NetDataContractSerializer
Hlavní rozdíl mezi DataContractSerializer a NetDataContractSerializer spočívá v tom, že DataContractSerializer používá názvy kontraktů dat, zatímco NetDataContractSerializer výstupem je úplné sestavení rozhraní .NET Framework a názvy typů v serializovaném XML. To znamená, že mezi koncovými body serializace a deserializace musí být sdíleny přesně stejné typy. To znamená, že se u NetDataContractSerializer nevyžaduje mechanismus známých typů, protože přesné typy, které mají být deserializovány, jsou vždy známé.
Může však dojít k několika problémům:
Bezpečnost. Všechny typy nalezené v deserializovaném souboru XML se načtou. To lze zneužít k vynucení načítání škodlivých typů. Použití
NetDataContractSerializers nedůvěryhodnými daty by mělo být provedeno pouze v případě, že se používá Serializace Binder (pomocí vlastnosti Binder nebo parametru konstruktoru). Vázací modul umožňuje načtení pouze bezpečných typů. Mechanismus Binder je shodný s mechanismem, který typy v oboru názvů System.Runtime.Serialization používají.Verzování. Použití úplných názvů typů a sestavení v jazyce XML výrazně omezuje způsob, jakým mohou být typy verzovány. Nelze změnit následující: názvy typů, obory názvů, názvy sestavení a verze sestavení. Nastavení vlastnosti AssemblyFormat nebo parametru konstruktoru na Simple místo výchozí hodnoty Full umožňuje změny verze sestavení, ale ne pro obecné typy parametrů.
Interoperabilita. Vzhledem k tomu, že názvy typů a sestavení rozhraní .NET Framework jsou zahrnuty v jazyce XML, platformy jiné než rozhraní .NET Framework nemají přístup k výsledným datům.
Výkon. Zápis názvů typů a sestavení výrazně zvyšuje velikost výsledného XML.
Tento mechanismus se podobá binární nebo SOAP serializaci používané při vzdálené komunikaci .NET Frameworku (konkrétně BinaryFormatter a SoapFormatter).
Použití NetDataContractSerializer se podobá použití DataContractSerializer, s následujícími rozdíly:
Konstruktory nevyžadují, abyste zadali kořenový typ. Můžete serializovat libovolný typ pomocí té samé instance
NetDataContractSerializer.Konstruktory nepřijímají seznam známých typů. Mechanismus známých typů není nutný, pokud jsou názvy typů serializovány do XML.
Konstruktory nepřijímají zástupce datového kontraktu. Místo toho přijímají parametr ISurrogateSelector nazvaný
surrogateSelector(který se mapuje na vlastnost SurrogateSelector). Jedná se o starší náhradní mechanismus.Konstruktory přijímají parametr
assemblyFormattypu FormatterAssemblyStyle, který se mapuje na vlastnost AssemblyFormat. Jak je popsáno dříve, lze ji použít k vylepšení možností správy verzí serializátoru. Je to totožné s mechanismem FormatterAssemblyStyle v binární nebo SOAP serializaci.Konstruktory přijímají parametr StreamingContext, nazývaný
context, který se mapuje na vlastnost Context. Můžete to použít k předání informací do typů, které se serializují. Toto použití je stejné jako mechanismus StreamingContext použitý v jiných třídách System.Runtime.Serialization.Serialize a Deserialize metody jsou aliasy pro WriteObject a ReadObject metody. Existují k zajištění konzistentnějšího programovacího modelu s binární serializací nebo serializací SOAP.
Další informace o těchto funkcích naleznete v tématu binární serializace.
Formáty XML, které NetDataContractSerializer a DataContractSerializer používají, nejsou obvykle kompatibilní. To znamená, že pokus o serializaci s jedním z těchto serializátorů a deserializace s druhým není podporovaný scénář.
Všimněte si také, že NetDataContractSerializer nevypíše úplný typ rozhraní .NET Framework a název sestavení pro každý uzel v grafu objektu. Výstupem jsou informace pouze tam, kde jsou nejednoznačné. To znamená, že vytváří výstup na úrovni kořenového objektu a pro všechny polymorfní případy.