Serialisasi dan Deserialisasi
Windows Communication Foundation (WCF) mencakup mesin serialisasi baru, yakni DataContractSerializer. DataContractSerializer menerjemahkan antara objek .NET Framework dan XML, dalam dua arah. Topik ini menjelaskan cara kerja pembuat serial.
Saat membuat serial objek .NET Framework, pembuat serial memahami berbagai model pemrograman serialisasi, termasuk model kontrak data baru. Untuk daftar lengkap jenis yang didukung, lihat Jenis yang Didukung oleh Pembuat Serial Kontrak Data. Untuk pengenalan tentang kontrak data, lihat Menggunakan Kontrak Data.
Saat mendeserialisasi XML, pembuat serial menggunakan kelas XmlReader dan XmlWriter. Ini juga mendukung kelas XmlDictionaryReader dan XmlDictionaryWriter untuk memungkinkannya menghasilkan XML yang dioptimalkan dalam beberapa kasus, seperti saat menggunakan format XML biner WCF.
WCF juga menyertakan pembuat serial pendamping, NetDataContractSerializer. NetDataContractSerializer:
- Tidak aman. Untuk informasi selengkapnya, lihat panduan keamanan BinaryFormatter.
- Mirip dengan pembuat serial BinaryFormatter dan SoapFormatter karena juga memancarkan nama jenis .NET Framework sebagai bagian dari data yang diserialisasikan.
- Digunakan ketika jenis yang sama dibagikan pada serialisasi dan deserialisasi berakhir.
Baik DataContractSerializer dan NetDataContractSerializer berasal dari kelas dasar yang sama, XmlObjectSerializer.
Peringatan
DataContractSerializer membuat serial string yang berisi karakter kontrol dengan nilai heksadesimal di bawah 20 sebagai entitas XML. Ini dapat menyebabkan masalah dengan klien non-WCF saat mengirim data tersebut ke layanan WCF.
Membuat DataContractSerializer
Membuat instans DataContractSerializer adalah langkah penting. Setelah konstruksi, Anda tidak dapat mengubah pengaturan apa pun.
Menentukan Jenis Root
Jenis root adalah jenis instans yang diserialisasikan atau dideserialisasi. DataContractSerializer memiliki banyak kelebihan konstruktor, tetapi, minimal, jenis root harus diberikan menggunakan parameter type
.
Pembuat Serial yang dibuat untuk jenis root tertentu tidak dapat digunakan untuk membuat serial (atau mendeserialisasi) jenis lain, kecuali jenis tersebut diturunkan dari jenis root. Contoh berikut menunjukkan dua kelas.
[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
Kode ini membuat instans dari DataContractSerializer
yang hanya dapat digunakan untuk membuat serial atau mendeserialisasi instans dari kelas Person
.
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.
Menentukan Jenis yang Diketahui
Jika polimorfisme terlibat dalam jenis yang diserialisasikan yang belum ditangani menggunakan atribut KnownTypeAttribute atau mekanisme lain, daftar kemungkinan jenis yang diketahui harus diteruskan ke konstruktor pembuat serial menggunakan parameter knownTypes
. Untuk informasi selengkapnya tentang jenis yang diketahui, lihat Jenis Kontrak Data yang Diketahui.
Contoh berikut menunjukkan kelas, LibraryPatron
, yang menyertakan kumpulan jenis tertentu, LibraryItem
. Kelas kedua mendefinisikan jenis LibraryItem
. Kelas ketiga dan empat (Book
dan Newspaper
) mewarisi dari kelas 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
Kode berikut membuat instans pembuat serial menggunakan parameter knownTypes
.
// 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.
Menentukan Nama Root dan Namespace Default
Biasanya, ketika sebuah objek diserialisasi, nama default dan namespace dari elemen XML terluar ditentukan sesuai dengan nama kontrak data dan namespace. Nama semua elemen dalam ditentukan dari nama anggota data, dan namespace mereka adalah namespace kontrak data. Contoh berikut menetapkan nilai Name
dan Namespace
dalam konstruktor kelas DataContractAttribute dan 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
Membuat serialisasi instans kelas Person
menghasilkan XML yang mirip dengan berikut ini.
<PersonContract xmlns="http://schemas.contoso.com">
<AddressMember>
<StreetMember>123 Main Street</StreetMember>
</AddressMember>
</PersonContract>
Namun, Anda dapat menyesuaikan nama default dan namespace elemen akar dengan meneruskan nilai parameter rootName
dan rootNamespace
ke konstruktor DataContractSerializer. Perhatikan bahwa rootNamespace
tidak memengaruhi namespace elemen yang terkandung yang sesuai dengan anggota data. Ini hanya mempengaruhi namespace dari elemen terluar.
Nilai-nilai ini dapat diteruskan sebagai string atau instans dari kelas XmlDictionaryString untuk memungkinkan pengoptimalannya menggunakan format XML biner.
Mengatur Kuota Objek Maksimum
Beberapa DataContractSerializer
kelebihan beban konstruktor memiliki parameter maxItemsInObjectGraph
. Parameter ini menentukan jumlah maksimum objek yang diserialisasikan pembuat serial atau deserialisasi dalam satu panggilan metode ReadObject. (Metode ini selalu membaca satu objek root, tetapi objek ini mungkin memiliki objek lain di anggota datanya. Objek tersebut mungkin memiliki objek lain, dan seterusnya.) Standarnya adalah 65536. Perhatikan bahwa saat membuat serial atau mendeserialisasi array, setiap entri array dihitung sebagai objek terpisah. Selain itu, perhatikan bahwa beberapa objek mungkin memiliki representasi memori yang besar, sehingga kuota ini saja mungkin tidak cukup untuk mencegah penolakan serangan layanan. Untuk informasi selengkapnya, lihat Pertimbangan Keamanan untuk Data. Jika Anda perlu meningkatkan kuota ini di luar nilai default, penting untuk melakukannya baik di sisi pengirim (serialisasi) dan penerima (deserialisasi) karena ini berlaku untuk keduanya saat membaca dan menulis data.
Perjalanan Pulang Pergi
Perjalanan pulang pergi terjadi saat objek dideserialisasi dan diserialisasi ulang dalam satu operasi. Dengan demikian, objek beralih dari XML ke instans objek, dan kembali lagi ke aliran XML.
Beberapa kelebihan konstruktor DataContractSerializer
memiliki parameter ignoreExtensionDataObject
, yang diatur ke false
secara default. Dalam mode default ini, data dapat dikirim dalam perjalanan pulang pergi dari versi kontrak data yang lebih baru melalui versi yang lebih lama dan kembali ke versi yang lebih baru tanpa kehilangan, selama kontrak data mengimplementasikan antarmuka IExtensibleDataObject. Misalnya, versi 1 dari kontrak data Person
berisi anggota data Name
dan PhoneNumber
, dan versi 2 menambahkan anggota Nickname
. Jika IExtensibleDataObject
diterapkan, saat mengirim informasi dari versi 2 ke versi 1, data Nickname
disimpan, dan kemudian dipancarkan kembali saat data diserialisasikan lagi; oleh karena itu, tidak ada data yang hilang dalam perjalanan pulang pergi. Untuk informasi selengkapnya, lihat Kontrak Data yang Kompatibel dengan Penerusan dan Versi Kontrak Data.
Masalah Keamanan dan Validitas Skema dengan Perjalanan Pulang Pergi
Perjalanan pulang pergi mungkin memiliki implikasi keamanan. Misalnya, deserialisasi dan penyimpanan data asing dalam jumlah besar mungkin merupakan risiko keamanan. Mungkin ada masalah keamanan terkait memancarkan kembali data ini sehingga tidak ada cara untuk memverifikasi, terutama jika tanda tangan digital terlibat. Misalnya, dalam skenario sebelumnya, titik akhir versi 1 dapat menandatangani nilai Nickname
yang berisi data berbahaya. Terakhir, mungkin ada masalah validitas skema: titik akhir mungkin ingin selalu memancarkan data yang secara ketat mematuhi kontrak yang dinyatakan dan bukan nilai tambahan. Dalam contoh sebelumnya, kontrak titik akhir versi 1 mengatakan bahwa itu hanya memancarkan Name
dan PhoneNumber
, dan jika validasi skema sedang digunakan, memancarkan nilai Nickname
tambahan menyebabkan validasi gagal.
Mengaktifkan dan Menonaktifkan Perjalanan Pulang Pergi
Untuk menonaktifkan perjalanan pulang pergi, jangan terapkan antarmuka IExtensibleDataObject. Jika Anda tidak memiliki kendali atas jenisnya, atur parameter ignoreExtensionDataObject
ke true
untuk mendapatkan efek yang sama.
Pelestarian Grafik Objek
Biasanya, pembuat serial tidak peduli dengan identitas objek, seperti pada kode berikut.
[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
Kode berikut membuat pesanan pembelian.
// 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
Perhatikan bahwa bidang billTo
dan shipTo
diatur ke instans objek yang sama. Namun, XML yang dihasilkan menduplikasi informasi yang diduplikasi, dan terlihat mirip dengan XML berikut.
<PurchaseOrder>
<billTo><street>123 Main St.</street></billTo>
<shipTo><street>123 Main St.</street></shipTo>
</PurchaseOrder>
Namun, pendekatan ini memiliki karakteristik berikut, yang mungkin tidak diinginkan:
Performa. Replikasi data tidak efisien.
Referensi melingkar. Jika objek mengacu pada dirinya sendiri, bahkan melalui objek lain, serialisasi dengan replikasi akan menghasilkan perulangan tak terbatas. (Pembuat Serial menampilkan SerializationException jika ini terjadi.)
Semantik. Terkadang penting untuk mempertahankan fakta bahwa dua referensi adalah ke objek yang sama, dan bukan ke dua objek yang identik.
Karena alasan ini, beberapa kelebihan konstruktor DataContractSerializer
memiliki parameter preserveObjectReferences
(defaultnya adalah false
). Ketika parameter ini diatur ke true
, metode khusus untuk mengodekan referensi objek, yang hanya dipahami oleh WCF, akan digunakan. Saat diatur ke true
, contoh kode XML sekarang menyerupai berikut ini.
<PurchaseOrder ser:id="1">
<billTo ser:id="2"><street ser:id="3">123 Main St.</street></billTo>
<shipTo ser:ref="2"/>
</PurchaseOrder>
Namespace "ser" mengacu pada namespace serialisasi standar, http://schemas.microsoft.com/2003/10/Serialization/
. Setiap bagian data diserialisasi hanya sekali dan diberi nomor ID, dan penggunaan selanjutnya menghasilkan referensi ke data yang sudah diserialisasi.
Penting
Jika atribut "id" dan "ref" ada dalam kontrak data XMLElement
, maka atribut "ref" diterapkan dan atribut "id" diabaikan.
Penting untuk memahami batasan mode ini:
XML yang dihasilkan
DataContractSerializer
denganpreserveObjectReferences
diatur ketrue
tidak dapat dioperasikan dengan teknologi lain, dan hanya dapat diakses oleh instansDataContractSerializer
lain, juga denganpreserveObjectReferences
diatur ketrue
.Tidak ada dukungan metadata (skema) untuk fitur ini. Skema yang dihasilkan hanya valid untuk kasus ketika
preserveObjectReferences
diatur kefalse
.Fitur ini dapat menyebabkan proses serialisasi dan deserialisasi berjalan lebih lambat. Meskipun data tidak harus direplikasi, perbandingan objek tambahan harus dilakukan dalam mode ini.
Perhatian
Saat mode preserveObjectReferences
diaktifkan, sangat penting untuk mengatur nilai maxItemsInObjectGraph
ke kuota yang benar. Karena cara array ditangani dalam mode ini, mudah bagi penyerang untuk membuat pesan berbahaya kecil yang menghasilkan konsumsi memori besar hanya dibatasi oleh kuota maxItemsInObjectGraph
.
Menentukan Pengganti Kontrak Data
Beberapa kelebihan konstruktor DataContractSerializer
memiliki parameter dataContractSurrogate
, yang dapat diatur ke null
. Jika tidak, Anda dapat menggunakannya untuk menentukan pengganti kontrak data, yang merupakan jenis yang mengimplementasikan antarmuka IDataContractSurrogate. Anda kemudian dapat menggunakan antarmuka untuk menyesuaikan proses serialisasi dan deserialisasi. Untuk mengetahui informasi selengkapnya, lihat Pengganti Kontrak Data.
Serialisasi
Informasi berikut berlaku untuk setiap kelas yang mewarisi dari XmlObjectSerializer, termasuk kelas DataContractSerializer dan NetDataContractSerializer.
Serialisasi Sederhana
Cara paling dasar untuk membuat serial objek adalah dengan meneruskannya ke metode WriteObject. Ada tiga kelebihan muatan, masing-masing untuk menulis ke Stream, XmlWriter, atau XmlDictionaryWriter. Dengan kelebihan muatan Stream, hasilnya adalah XML dalam pengodean UTF-8. Dengan kelebihan muatan XmlDictionaryWriter, pembuat serial mengoptimalkan outputnya untuk XML biner.
Saat menggunakan metode WriteObject, pembuat serial menggunakan nama default dan namespace untuk elemen pembungkus dan menuliskannya bersama dengan isinya (lihat bagian "Menentukan Nama Root dan Namespace Default" sebelumnya).
Contoh berikut menunjukkan penulisan dengan 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)
Penulisan ini menghasilkan XML yang mirip dengan berikut ini.
<Person>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
Serialisasi Langkah-demi-Langkah
WriteStartObjectGunakan metode, WriteObjectContent, dan WriteEndObject untuk menulis elemen akhir, menulis konten objek, dan menutup elemen pembungkus.
Catatan
Tidak ada kelebihan muatan Stream metode ini.
Serialisasi selangkah demi selangkah ini memiliki dua kegunaan umum. Salah satunya adalah dengan menyisipkan konten seperti atribut atau komentar antara WriteStartObject
dan WriteObjectContent
, seperti yang ditunjukkan pada contoh berikut.
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)
Penulisan ini menghasilkan XML yang mirip dengan berikut ini.
<Person serializedBy="myCode">
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</Person>
Penggunaan umum lainnya adalah menghindari penggunaan WriteStartObject dan WriteEndObject seluruhnya, dan untuk menulis elemen pembungkus khusus Anda sendiri (atau bahkan melewati penulisan pembungkus secara keseluruhan), seperti yang ditunjukkan pada kode berikut.
xdw.WriteStartElement("MyCustomWrapper");
dcs.WriteObjectContent(xdw, p);
xdw.WriteEndElement();
xdw.WriteStartElement("MyCustomWrapper")
dcs.WriteObjectContent(xdw, p)
xdw.WriteEndElement()
Penulisan ini menghasilkan XML yang mirip dengan berikut ini.
<MyCustomWrapper>
<Name>Jay Hamlin</Name>
<Address>123 Main St.</Address>
</MyCustomWrapper>
Catatan
Menggunakan serialisasi langkah demi langkah dapat mengakibatkan XML skema tidak valid.
Deserialisasi
Informasi berikut berlaku untuk setiap kelas yang mewarisi dari XmlObjectSerializer, termasuk kelas DataContractSerializer dan NetDataContractSerializer.
Cara paling dasar untuk membatalkan serialisasi objek adalah dengan memanggil salah satu kelebihan muatan metode ReadObject. Ada tiga kelebihan muatan, masing-masing untuk membaca dengan XmlDictionaryReader, XmlReader
, atau Stream
. Perhatikan bahwa kelebihan muatan Stream
membuat XmlDictionaryReader tekstual yang tidak dilindungi oleh kuota apa pun, dan harus digunakan hanya untuk membaca data tepercaya.
Perhatikan juga bahwa objek yang dikembalikan oleh metode ReadObject
harus dilemparkan ke jenis yang sesuai.
Kode berikut membuat instans dari DataContractSerializer dan XmlDictionaryReader, lalu membatalkan serialisasi instans 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)
Sebelum memanggil metode ReadObject, posisikan pembaca XML pada elemen pembungkus atau pada node non-konten yang mendahului elemen pembungkus. Anda dapat melakukannya dengan memanggil metode Read dari XmlReader atau turunannya, dan menguji NodeType, seperti yang ditunjukkan pada kode berikut.
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("{0} {1} id:{2}",
p.Name , p.Address);
}
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
Perhatikan bahwa Anda dapat membaca atribut pada elemen pembungkus ini sebelum menyerahkan pembaca ke ReadObject
.
Saat menggunakan salah satu dari kelebihan muatan ReadObject
sederhana, deserializer mencari nama default dan namespace pada elemen pembungkus (lihat bagian sebelumnya, "Menentukan Nama Root dan Namespace Default") dan menampilkan pengecualian jika menemukan elemen yang tidak diketahui. Dalam contoh sebelumnya, elemen pembungkus <Person>
diharapkan. Metode IsStartObject dipanggil untuk memverifikasi bahwa pembaca diposisikan pada elemen yang diberi nama seperti yang diharapkan.
Ada cara untuk menonaktifkan pemeriksaan nama elemen pembungkus ini; beberapa kelebihan muatan dari metode ReadObject
mengambil parameter Boolean verifyObjectName
, yang diatur ke true
secara default. Jika diatur ke false
, nama dan namespace elemen pembungkus akan diabaikan. Ini berguna untuk membaca XML yang ditulis menggunakan mekanisme serialisasi langkah-demi-langkah yang dijelaskan sebelumnya.
Menggunakan NetDataContractSerializer
Perbedaan utama antara DataContractSerializer
dan NetDataContractSerializer adalah bahwa DataContractSerializer
menggunakan nama kontrak data, sedangkan NetDataContractSerializer
menghasilkan rakitan .NET Framework lengkap dan nama jenis dalam XML serial. Ini berarti bahwa jenis yang sama persis harus dibagi antara titik akhir serialisasi dan deserialisasi. Ini berarti bahwa mekanisme jenis yang diketahui tidak diperlukan dengan NetDataContractSerializer
karena jenis pasti yang akan dideserialisasi selalu diketahui.
Namun, beberapa masalah dapat terjadi:
Keamanan. Jenis apa pun yang ditemukan dalam XML yang sedang dideserialisasi akan dimuat. Ini dapat dimanfaatkan untuk memaksa pemuatan jenis berbahaya. Menggunakan
NetDataContractSerializer
dengan data yang tidak dipercaya harus dilakukan hanya jika Pengikat Serialisasi digunakan (menggunakan properti Binder atau parameter konstruktor). Pengikat hanya mengizinkan jenis yang aman untuk dimuat. Mekanisme Binder identik dengan yang diketik dalam penggunaan namespace System.Runtime.Serialization.Penerapan versi. Menggunakan jenis lengkap dan nama rakitan dalam XML sangat membatasi bagaimana jenis dapat dibuatkan versi. Berikut ini tidak dapat diubah: nama jenis, namespace, nama rakitan, dan versi rakitan. Mengatur properti AssemblyFormat atau parameter konstruktor ke Simple, bukan nilai default Full memungkinkan perubahan versi rakitan, tetapi tidak untuk jenis parameter umum.
Interoperabilitas. Karena jenis .NET Framework dan nama rakitan disertakan dalam XML, platform selain .NET Framework tidak dapat mengakses data yang dihasilkan.
Performa. Menuliskan jenis dan nama rakitan secara signifikan akan meningkatkan ukuran XML yang dihasilkan.
Mekanisme ini mirip dengan serialisasi biner atau SOAP yang digunakan oleh .NET Framework jarak jauh (khususnya, BinaryFormatter dan SoapFormatter).
Menggunakan NetDataContractSerializer
mirip dengan menggunakan DataContractSerializer
, dengan perbedaan berikut:
Konstruktor tidak mengharuskan Anda untuk menentukan jenis root. Anda dapat membuat cerita bersambung jenis apa pun dengan instans
NetDataContractSerializer
yang sama.Konstruktor tidak menerima daftar jenis yang diketahui. Mekanisme jenis yang diketahui tidak diperlukan jika nama jenis diserialisasikan ke dalam XML.
Konstruktor tidak menerima pengganti kontrak data. Sebagai gantinya, konstruktor menerima parameter ISurrogateSelector yang disebut
surrogateSelector
(yang memetakan ke properti SurrogateSelector). Ini adalah mekanisme pengganti warisan.Konstruktor menerima parameter yang disebut
assemblyFormat
dari FormatterAssemblyStyle yang dipetakan ke properti AssemblyFormat. Seperti yang telah dibahas sebelumnya, ini dapat digunakan untuk meningkatkan kemampuan pembuatan versi pembuat serial. Ini identik dengan mekanisme FormatterAssemblyStyle dalam serialisasi biner atau SOAP.Konstruktor menerima parameter StreamingContext yang disebut
context
yang memetakan ke properti Context. Anda dapat menggunakan ini untuk meneruskan informasi ke dalam tipe yang diserialkan. Penggunaan ini identik dengan mekanisme StreamingContext yang digunakan di kelas System.Runtime.Serialization lainnya.Metode Serialize dan Deserialize adalah alias untuk metode WriteObject dan ReadObject. Ini ada untuk menyediakan model pemrograman yang lebih konsisten dengan serialisasi biner atau SOAP.
Untuk informasi selengkapnya tentang fitur ini, lihat Serialisasi Biner.
Format XML yang digunakan NetDataContractSerializer
dan DataContractSerializer
biasanya tidak kompatibel. Artinya, mencoba membuat serial dengan salah satu pembuat serial ini dan mendeserialisasi dengan yang lain bukanlah skenario yang didukung.
Perhatikan juga bahwa NetDataContractSerializer
tidak menampilkan jenis .NET Framework dan nama rakitan lengkap untuk setiap node dalam grafik objek. Ini mengeluarkan informasi tersebut hanya di tempat yang ambigu. Artinya, output pada tingkat objek root dan untuk kasus polimorfik apa pun.