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 dengan preserveObjectReferences diatur ke true tidak dapat dioperasikan dengan teknologi lain, dan hanya dapat diakses oleh instans DataContractSerializer lain, juga dengan preserveObjectReferences diatur ke true.

  • Tidak ada dukungan metadata (skema) untuk fitur ini. Skema yang dihasilkan hanya valid untuk kasus ketika preserveObjectReferences diatur ke false.

  • 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.

Lihat juga