Bagikan melalui


Menggunakan Kelas XmlSerializer

Windows Communication Foundation (WCF) dapat menggunakan dua teknologi serialisasi yang berbeda untuk mengubah data dalam aplikasi Anda menjadi XML yang ditransmisikan antara klien dan layanan: DataContractSerializer dan XmlSerializer.

DataContractSerializer

Secara default, WCF menggunakan kelas DataContractSerializer untuk melakukan serialisasi jenis data. Serializer ini mendukung jenis berikut:

  • Jenis primitif (misalnya, bilangan bulat, string, dan larik byte), serta beberapa jenis khusus, seperti XmlElement dan DateTime, yang diperlakukan sebagai primitif.

  • Jenis kontrak data (jenis yang ditandai dengan atribut DataContractAttribute).

  • Jenis yang ditandai dengan atribut SerializableAttribute, yang mencakup jenis yang mengimplementasikan antarmuka ISerializable.

  • Jenis yang mengimplementasikan antarmuka IXmlSerializable.

  • Banyak jenis koleksi umum, yang mencakup banyak jenis koleksi generik.

Banyak jenis .NET Framework jatuh ke dalam dua kategori terakhir dan dengan demikian dapat diserialisasikan. Larik dari jenis yang dapat diserialisasikan juga termasuk yang dapat diserialisasikan. Untuk daftar lengkapnya, lihat Menentukan Transfer Data dalam Kontrak Layanan.

DataContractSerializer, yang digunakan bersama dengan jenis kontrak data, adalah cara yang disarankan untuk menulis layanan WCF baru. Untuk informasi selengkapnya, lihat Menggunakan Kontrak Data.

XmlSerializer

WCF juga mendukung kelas XmlSerializer. Kelas XmlSerializer ini tidak unik untuk WCF. Itu adalah mesin serialisasi yang sama yang digunakan Layanan web ASP.NET. Kelas XmlSerializer mendukung serangkaian jenis yang jauh lebih sempit daripada kelas DataContractSerializer, tetapi memungkinkan kontrol yang lebih besar atas XML yang dihasilkan dan mendukung lebih banyak standar bahasa Skema XML (XSD). Kelas tersebut juga tidak membutuhkan atribut deklaratif apa pun pada jenis yang dapat diserialisasikan. Untuk informasi selengkapnya, lihat topik Serialisasi XML di dokumentasi .NET Framework. Kelas XmlSerializer tidak mendukung jenis kontrak data.

Saat menggunakan Svcutil.exe atau fitur Tambahkan Referensi Layanan di Visual Studio untuk menghasilkan kode klien untuk layanan pihak ketiga, atau untuk mengakses skema pihak ketiga, serializer yang sesuai secara otomatis dipilih untuk Anda. Jika skema tidak kompatibel dengan DataContractSerializer, XmlSerializer akan dipilih.

Beralih ke XmlSerializer

Terkadang, Anda mungkin harus beralih secara manual ke XmlSerializer. Ini terjadi, misalnya, dalam kasus-kasus berikut:

  • Saat memigrasikan aplikasi dari layanan web ASP.NET ke WCF, Anda mungkin ingin menggunakan kembali jenis yang sudah ada dan kompatibel dengan XmlSerializer alih-alih membuat jenis kontrak data baru.

  • Ketika kontrol yang tepat atas XML yang muncul dalam pesan adalah hal penting, tetapi dokumen Bahasa Deskripsi Layanan Web (WSDL) tidak tersedia, misalnya, ketika membuat layanan dengan jenis yang harus mematuhi skema standar tertentu dan diterbitkan yang tidak kompatibel dengan DataContractSerializer.

  • Saat membuat layanan yang mengikuti standar Pengodean SOAP lama.

Dalam kasus ini dan kasus lainnya, Anda dapat beralih secara manual ke kelas XmlSerializer dengan menerapkan atribut XmlSerializerFormatAttribute ke layanan Anda, seperti yang ditunjukkan dalam kode berikut.

[ServiceContract]
[XmlSerializerFormat]
public class BankingService
{
[OperationContract]
    public void ProcessTransaction(BankingTransaction bt)
    {
        // Code not shown.
    }
}

//BankingTransaction is not a data contract class,
//but is an XmlSerializer-compatible class instead.
public class BankingTransaction
{
    [XmlAttribute]
    public string Operation;
    [XmlElement]
    public Account fromAccount;
    [XmlElement]
    public Account toAccount;
    [XmlElement]
    public int amount;
}
//Notice that the Account class must also be XmlSerializer-compatible.
<ServiceContract(), XmlSerializerFormat()> _
Public Class BankingService
    <OperationContract()> _
    Public Sub ProcessTransaction(ByVal bt As BankingTransaction)
        ' Code not shown.
    End Sub
End Class


' BankingTransaction is not a data contract class,
' but is an XmlSerializer-compatible class instead.

Public Class BankingTransaction
    <XmlAttribute()> _
    Public Operation As String
    <XmlElement()> _
    Public fromAccount As Account
    <XmlElement()> _
    Public toAccount As Account
    <XmlElement()> _
    Public amount As Integer
End Class
'Notice that the Account class must also be XmlSerializer-compatible.

Pertimbangan Keamanan

Catatan

Penting untuk berhati-hati saat mengganti mesin serialisasi. Jenis yang sama dapat diserialisasikan ke XML secara berbeda tergantung pada serializer yang digunakan. Jika Anda secara tidak sengaja menggunakan serializer yang salah, Anda mungkin mengungkapkan informasi dari jenis yang tidak ingin Anda ungkapkan.

Misalnya, kelas DataContractSerializer hanya menserialisasikan anggota yang ditandai dengan atribut DataMemberAttribute saat membuat serial jenis kontrak data. Kelas XmlSerializer ini menserialisasikan anggota publik mana pun. Lihat jenis dalam kode berikut.

[DataContract]
public class Customer
{
    [DataMember]
    public string firstName;
    [DataMember]
    public string lastName;
    public string creditCardNumber;
}
<DataContract()> _
Public Class Customer
    <DataMember()> _
    Public firstName As String
    <DataMember()> _
    Public lastName As String
    Public creditCardNumber As String
End Class

Jika jenisnya secara tidak sengaja digunakan dalam kontrak layanan tempat kelas XmlSerializer dipilih, anggota creditCardNumber akan diserialisasikan, yang mungkin tidak dimaksudkan.

Meskipun kelas DataContractSerializer adalah opsi default, Anda dapat secara eksplisit memilihnya untuk layanan Anda (meskipun melakukan ini seharusnya tidak pernah diharuskan) dengan menerapkan atribut DataContractFormatAttribute ke jenis kontrak layanan.

Serializer yang digunakan untuk layanan ini merupakan bagian integral dari kontrak dan tidak dapat diubah dengan memilih pengikatan yang berbeda atau dengan mengubah pengaturan konfigurasi lainnya.

Pertimbangan keamanan penting lainnya berlaku untuk kelas XmlSerializer. Pertama, sangat disarankan agar setiap aplikasi WCF yang menggunakan kelas XmlSerializer ditandatangani dengan kunci yang diamankan dari pengungkapan. Rekomendasi ini berlaku baik ketika pengalihan manual ke XmlSerializer dilakukan dan ketika pengalihan otomatis dilakukan (dengan Svcutil.exe, Tambahkan Referensi Layanan, atau alat serupa). Ini karena mesin serialisasi XmlSerializer mendukung pemuatan rakitan serialisasi yang telah dihasilkan sebelumnya selama ditandatangani dengan kunci yang sama dengan aplikasi. Aplikasi yang tidak ditandatangani benar-benar tidak terlindungi dari kemungkinan rakitan berbahaya yang cocok dengan nama yang diperkirakan dari rakitan serialisasi yang dihasilkan sebelumnya yang ditempatkan di folder aplikasi atau singgahan perakitan global. Tentu saja, penyerang harus terlebih dahulu mendapatkan akses tulis ke salah satu dari dua lokasi ini untuk mencoba tindakan ini.

Ancaman lain yang ada setiap kali Anda menggunakan XmlSerializer berkaitan dengan akses tulis ke folder sementara sistem. Mesin serialisasi XmlSerializer membuat dan menggunakan rakitan serialisasi sementara dalam folder ini. Anda harus menyadari bahwa setiap proses dengan akses tulis ke folder sementara dapat menimpa rakitan serialisasi ini dengan kode berbahaya.

Aturan untuk dukungan XmlSerializer

Anda tidak dapat langsung menerapkan atribut yang kompatibel XmlSerializer untuk parameter operasi kontrak atau nilai pengembalian. Namun, dapat diterapkan pada pesan yang berjenis (bagian isi kontrak pesan), seperti yang ditunjukkan dalam kode berikut.

[ServiceContract]
[XmlSerializerFormat]
public class BankingService
{
    [OperationContract]
    public void ProcessTransaction(BankingTransaction bt)
    {
        //Code not shown.
    }
}

[MessageContract]
public class BankingTransaction
{
    [MessageHeader]
    public string Operation;
    [XmlElement, MessageBodyMember]
    public Account fromAccount;
    [XmlElement, MessageBodyMember]
    public Account toAccount;
    [XmlAttribute, MessageBodyMember]
    public int amount;
}
<ServiceContract(), XmlSerializerFormat()> _
Public Class BankingService
    <OperationContract()> _
    Public Sub ProcessTransaction(ByVal bt As BankingTransaction)
        'Code not shown.
    End Sub
End Class

<MessageContract()> _
Public Class BankingTransaction
    <MessageHeader()> _
    Public Operation As String
    <XmlElement(), MessageBodyMember()> _
    Public fromAccount As Account
    <XmlElement(), MessageBodyMember()> _
    Public toAccount As Account
    <XmlAttribute(), MessageBodyMember()> _
    Public amount As Integer
End Class

Saat diterapkan ke anggota pesan yang diketik, atribut ini mengambil alih properti yang bertentangan pada atribut pesan yang berjenis. Misalnya, dalam kode berikut, ElementName mengambil alih Name.

    [MessageContract]
    public class BankingTransaction
    {
        [MessageHeader] public string Operation;

        //This element will be <fromAcct> and not <from>:
        [XmlElement(ElementName="fromAcct"), MessageBodyMember(Name="from")]
        public Account fromAccount;

        [XmlElement, MessageBodyMember]
        public Account toAccount;

        [XmlAttribute, MessageBodyMember]
        public int amount;
}
<MessageContract()> _
Public Class BankingTransaction
    <MessageHeader()> _
    Public Operation As String

    'This element will be <fromAcct> and not <from>:
    <XmlElement(ElementName:="fromAcct"), _
        MessageBodyMember(Name:="from")> _
    Public fromAccount As Account

    <XmlElement(), MessageBodyMember()> _
    Public toAccount As Account

    <XmlAttribute(), MessageBodyMember()> _
    Public amount As Integer
End Class

Atribut MessageHeaderArrayAttribute tidak didukung saat menggunakan XmlSerializer.

Catatan

Dalam hal ini, XmlSerializer melemparkan pengecualian berikut, yang dirilis sebelum WCF: "Elemen yang dinyatakan pada tingkat atas skema tidak boleh memiliki maxOccurs> 1. Menyediakan elemen pembungkus untuk 'lebih banyak' dengan menggunakan XmlArray atau XmlArrayItem alih-alih XmlElementAttribute, atau dengan menggunakan Gaya parameter terbungkus."

Jika Anda menerima pengecualian seperti itu, selidiki apakah situasi ini berlaku.

WCF tidak mendukung atribut SoapIncludeAttribute dan XmlIncludeAttribute dalam kontrak pesan dan kontrak operasi; gunakan atribut sebagai gantinya KnownTypeAttribute.

Jenis yang Mengimplementasikan Antarmuka IXmlSerializable

Jenis yang mengimplementasikan antarmuka IXmlSerializable sepenuhnya didukung oleh DataContractSerializer. Atribut XmlSchemaProviderAttribute harus selalu diterapkan ke jenis-jenis ini untuk mengontrol skemanya.

Peringatan

Jika Anda menserialisasikan jenis polimorfik, Anda harus menerapkannya XmlSchemaProviderAttribute ke jenis untuk memastikan jenis yang benar diserialisasikan.

Ada tiga macam jenis yang mengimplementasikan IXmlSerializable: jenis yang mewakili konten arbitrer, jenis yang mewakili elemen tunggal, dan jenis DataSet lama.

  • Jenis konten menggunakan metode penyedia skema yang ditentukan oleh atribut XmlSchemaProviderAttribute. Metode tidak mengembalikan properti null dan IsAny pada atribut dibiarkan tetap pada nilai default false. Ini adalah penggunaan jenis IXmlSerializable yang paling umum.

  • Jenis elemen digunakan ketika jenis IXmlSerializable harus mengontrol nama elemen akarnya sendiri. Untuk menandai jenis sebagai jenis elemen, atur properti IsAny pada atribut XmlSchemaProviderAttribute ke true atau kembalikan null dari metode penyedia skema. Memiliki metode penyedia skema bersifat opsional untuk jenis elemen - Anda dapat menentukan null alih-alih nama metode di XmlSchemaProviderAttribute. Namun, jika IsAny adalah true dan metode penyedia skema sudah ditentukan, metode harus mengembalikan null.

  • Jenis DataSet lama adalah jenis IXmlSerializable yang tidak ditandai dengan atribut XmlSchemaProviderAttribute. Sebaliknya, mereka mengandalkan metode GetSchema untuk pembuatan skema. Pola ini digunakan untuk jenis DataSet dan himpunan data berjenisnya menghasilkan kelas dalam versi .NET Framework sebelumnya, tetapi sekarang sudah usang dan didukung hanya karena alasan lama. Jangan mengandalkan pola ini dan selalu terapkan XmlSchemaProviderAttribute ke jenis IXmlSerializable Anda.

Jenis Konten IXmlserializable

Saat menserialisasikan anggota data dari jenis yang mengimplementasikan IXmlSerializable dan merupakan jenis konten seperti yang ditentukan sebelumnya, serializer menulis elemen pembungkus untuk anggota data dan meneruskan kontrol ke metode WriteXml. Implementasi WriteXml dapat menulis XML apa pun, yang mencakup penambahan atribut ke elemen pembungkus. Setelah WriteXml selesai, serializer menutup elemen.

Saat mendeserialisasi anggota data dari jenis yang mengimplementasikan IXmlSerializable dan merupakan jenis konten seperti yang ditentukan sebelumnya, deserializer memposisikan pembaca XML pada elemen pembungkus untuk anggota data dan meneruskan kontrol ke metode ReadXml. Metode harus membaca seluruh elemen, termasuk tag awal dan akhir. Pastikan kode ReadXml Anda menangani kasus di mana elemen kosong. Selain itu, implementasi ReadXml Anda tidak boleh mengandalkan elemen penyelubung yang dinamai dengan cara khusus. Nama yang dipilih oleh serializer dapat bervariasi.

Diizinkan untuk menetapkan jenis konten IXmlSerializable secara polimorfik, misalnya, ke anggota data jenis Object. Juga diizinkan bagi instans jenis untuk menjadi null. Terakhir, dimungkinkan untuk menggunakan jenis IXmlSerializable dengan preservasi grafik objek yang aktif dan dengan NetDataContractSerializer. Semua fitur ini mengharuskan serializer WCF untuk melampirkan atribut tertentu ke dalam elemen pembungkus ("nil" dan "type" di namespace Instans Skema XML dan "Id", "Ref", "Type" dan "Assembly" di namespace khusus WCF).

Atribut yang akan Diabaikan saat Menerapkan ReadXml

Sebelum meneruskan kontrol ke kode ReadXml Anda, deserializer memeriksa elemen XML, mendeteksi atribut XML khusus ini, dan bertindak atasnya. Misalnya, jika "nil" adalah true, nilai null dideserialisasi dan ReadXml tidak dipanggil. Jika polimorfisme terdeteksi, isi elemen akan dideserialisasi seolah-olah itu adalah jenis yang berbeda. Implementasi ReadXml jenis yang ditetapkan secara polimorfik dipanggil. Bagaimanapun, implementasi ReadXml harus mengabaikan atribut khusus ini karena ditangani oleh deserializer.

Pertimbangan Skema untuk Jenis Konten IXmlSerializable

Saat mengekspor skema dan jenis konten IXmlSerializable, metode penyedia skema akan dipanggil. XmlSchemaSet diteruskan ke metode penyedia skema. Metode ini dapat menambahkan skema apa pun yang valid ke set skema. Set skema berisi skema yang sudah diketahui pada saat ekspor skema terjadi. Ketika metode penyedia skema harus menambahkan item ke set skema, metode tersebut harus menentukan apakah XmlSchema dengan namespace yang sesuai sudah ada dalam set. Jika ya, metode penyedia skema harus menambahkan item baru ke XmlSchema yang sudah ada. Jika tidak, instans XmlSchema baru harus dibuat. Ini penting jika array jenis IXmlSerializable sedang digunakan. Misalnya, jika Anda memiliki jenis IXmlSerializable yang diekspor sebagai jenis "A" di namespace "B", ada kemungkinan bahwa pada saat metode penyedia skema dipanggil, set skema sudah berisi skema untuk "B" untuk menampung jenis "ArrayOfA".

Selain menambahkan jenis ke XmlSchemaSet, metode penyedia skema untuk jenis konten harus mengembalikan nilai non-null. Ini dapat mengembalikan XmlQualifiedName yang menentukan nama jenis skema yang akan digunakan untuk jenis IXmlSerializable yang diberikan. Nama yang memenuhi syarat ini juga berfungsi sebagai nama kontrak data dan namespace untuk jenis tersebut. Diizinkan untuk mengembalikan jenis yang tidak ada dalam set skema segera saat metode penyedia skema kembali. Namun, diperkirakan bahwa pada saat semua jenis terkait diekspor (metode Export dipanggil untuk semua jenis yang relevan pada XsdDataContractExporter dan properti Schemas diakses), jenisnya ada dalam set skema. Mengakses properti Schemas sebelum semua panggilan Export yang relevan dilakukan dapat menghasilkan XmlSchemaException. Untuk informasi selengkapnya proses ekspor, lihat Mengekspor Skema dari Kelas.

Metode penyedia skema juga dapat mengembalikan XmlSchemaType untuk digunakan. Jenis ini mungkin anonim atau mungkin juga tidak. Jika bersifat anonim, skema untuk jenis IXmlSerializable tersebut diekspor sebagai jenis anonim setiap kali jenis IXmlSerializable digunakan sebagai anggota data. Jenis IXmlSerializable masih memiliki namespace dan nama kontrak data. (Ini ditentukan seperti yang dijelaskan dalam Nama Kontrak Data kecuali bahwa atribut DataContractAttribute tidak dapat digunakan untuk mengkustomisasi nama). Jika tidak anonim, itu harus termasuk dari salah satu jenis dalam XmlSchemaSet. Kasus ini setara dengan mengembalikan jenis XmlQualifiedName.

Selain itu, deklarasi elemen global diekspor untuk jenis tersebut. Jika jenis tidak memiliki atribut XmlRootAttribute yang diterapkan padanya, elemen memiliki nama dan namespace yang sama dengan kontrak data, dan properti "nillable"-nya adalah true. Satu-satunya pengecualian untuk ini adalah namespace layanan skema (http://www.w3.org/2001/XMLSchema) – jika kontrak data jenis berada di namespace layanan ini, elemen global yang sesuai berada di namespace kosong karena dilarang menambahkan elemen baru ke namespace layanan skema. Jika jenis memiliki atribut XmlRootAttribute yang diterapkan padanya, deklarasi elemen global diekspor menggunakan properti berikut: ElementName, Namespace, dan IsNullable. Default dengan penerapan XmlRootAttribute adalah nama kontrak data, namespace kosong dan "nillable" bernilai true.

Aturan deklarasi elemen global yang sama berlaku untuk jenis himpunan data lama. Perhatikan bahwa XmlRootAttribute tidak dapat mengambil alih deklarasi elemen global yang ditambahkan melalui kode kustom, baik itu ditambahkan ke XmlSchemaSet menggunakan metode penyedia skema atau melalui GetSchema untuk jenis himpunan data lama.

Jenis Elemen IXmlSerializable

Jenis elemen IXmlSerializable dapat memiliki properti IsAny yang diatur ke true atau memiliki metode penyedia skema yang mengembalikan null.

Melakukan serialisasi dan deserialisasi jenis elemen sangat mirip dengan serialisasi dan deserialisasi pada jenis konten. Namun, ada beberapa perbedaan penting:

  • Implementasi WriteXml diperkirakan untuk menulis tepat satu elemen (yang tentu saja dapat berisi beberapa elemen turunan). Tidak boleh menulis atribut di luar elemen tunggal ini, elemen saudara ganda atau konten campuran. Elemen bisa saja kosong.

  • Implementasi ReadXml tidak boleh membaca elemen penyelubung. Diperkirakan untuk membaca satu elemen yang dihasilkan WriteXml.

  • Saat melakukan serialisasi jenis elemen secara teratur (misalnya, sebagai anggota data dalam kontrak data), serializer menghasilkan elemen pembungkus sebelum memanggil WriteXml, seperti halnya jenis konten. Namun, saat menserialisasikan jenis elemen di tingkat atas, serializer biasanya tidak menghasilkan elemen pembungkus sama sekali di sekitar elemen yang ditulis WriteXml, kecuali nama akar dan namespace ditentukan secara eksplisit saat membangun serializer di konstruktor DataContractSerializer atau NetDataContractSerializer. Untuk informasi selengkapnya, lihat Serialisasi dan Deserialisasi.

  • Saat menserialisasikan jenis elemen di tingkat atas tanpa menentukan nama akar dan namespace pada waktu konstruksi, WriteStartObject dan WriteEndObject pada dasarnya tidak melakukan apa pun dan WriteObjectContent memanggil WriteXml. Dalam mode ini, objek yang sedang diserialisasikan tidak boleh null dan tidak dapat ditetapkan secara polimorfik. Selain itu, preservasi grafik objek tidak dapat diaktifkan dan NetDataContractSerializer tidak dapat digunakan.

  • Saat mendeserialisasi jenis elemen di tingkat atas tanpa menentukan nama akar dan namespace layanan pada waktu konstruksi, IsStartObject mengembalikan true jika dapat menemukan awal dari elemen apa pun. ReadObject dengan parameter verifyObjectName yang diatur ke true berperilaku dengan cara yang sama seperti IsStartObject sebelum benar-benar membaca objek. ReadObject kemudian meneruskan kontrol ke metode ReadXml.

Skema yang diekspor untuk jenis elemen sama dengan untuk jenis XmlElement seperti yang dijelaskan di bagian sebelumnya, kecuali bahwa metode penyedia skema dapat menambahkan skema tambahan apa pun ke XmlSchemaSet seperti halnya jenis konten. Menggunakan atribut XmlRootAttribute dengan jenis elemen tidak diizinkan, dan deklarasi elemen global tidak pernah dikeluarkan untuk jenis ini.

Perbedaan dari XmlSerializer

Antarmuka IXmlSerializable dan atribut XmlSchemaProviderAttribute dan XmlRootAttribute juga dipahami oleh XmlSerializer. Namun, ada beberapa perbedaan dalam cara perlakuannya di model kontrak data. Perbedaan penting dirangkum dalam daftar berikut:

  • Metode penyedia skema harus bersifat publik untuk digunakan dalam XmlSerializer, tetapi tidak harus bersifat publik untuk digunakan dalam model kontrak data.

  • Metode penyedia skema dipanggil ketika IsAny adalah true dalam model kontrak data tetapi tidak dengan XmlSerializer.

  • Ketika atribut XmlRootAttribute tidak ada untuk konten atau jenis himpunan data lama, XmlSerializer mengekspor deklarasi elemen global dalam namespace layanan kosong. Dalam model kontrak data, namespace layanan yang digunakan biasanya adalah namespace layanan kontrak data seperti yang dijelaskan sebelumnya.

Waspadai perbedaan-perbedaan ini saat membuat jenis yang digunakan dengan kedua teknologi serialisasi.

Mengimpor Skema IXmlSerializable

Saat mengimpor skema yang dihasilkan dari jenis IXmlSerializable, ada beberapa kemungkinan:

  • Skema yang dihasilkan mungkin adalah skema kontrak data yang valid seperti yang dijelaskan dalam Referensi Skema Kontrak Data. Dalam hal ini, skema dapat diimpor seperti biasa dan jenis kontrak data reguler akan dihasilkan.

  • Skema yang dihasilkan mungkin bukan skema kontrak data yang valid. Misalnya, metode penyedia skema Anda dapat menghasilkan skema yang melibatkan atribut XML yang tidak didukung dalam model kontrak data. Dalam hal ini, Anda dapat mengimpor skema sebagai jenis IXmlSerializable. Mode impor ini tidak aktif secara default tetapi dapat dengan mudah diaktifkan - misalnya, dengan parameter baris perintah /importXmlTypes ke Alat Utilitas Metadata ServiceModel (Svcutil.exe). Ini dijelaskan secara rinci dalam Mengimpor Skema untuk Menghasilkan Kelas. Perhatikan bahwa Anda harus bekerja secara langsung dengan XML untuk instans jenis Anda. Anda juga dapat mempertimbangkan untuk menggunakan teknologi serialisasi yang berbeda yang mendukung berbagai skema – lihat topik tentang penggunaan XmlSerializer.

  • Anda mungkin ingin menggunakan kembali jenis IXmlSerializable yang ada di proksi alih-alih menghasilkan yang baru. Dalam hal ini, fitur jenis yang direferensikan yang dijelaskan dalam topik Mengimpor Skema untuk Menghasilkan Jenis dapat digunakan untuk menunjukkan jenis yang akan digunakan kembali. Ini sesuai dengan penggunaan parameter /reference di svcutil.exe, yang menentukan rakitan yang berisi jenis yang akan digunakan kembali.

Perilaku Lama XmlSerializer

Pada .NET Framework 4.0 dan sebelumnya, XmlSerializer menghasilkan rakitan serialisasi sementara dengan menulis kode C# ke file. File itu kemudian dikompilasi menjadi rakitan. Perilaku ini memiliki beberapa konsekuensi yang tidak diinginkan seperti memperlambat waktu startup untuk serializer. Pada .NET Framework 4.5, perilaku ini diubah untuk menghasilkan rakitan tanpa memerlukan penggunaan pengompilasi. Beberapa pengembang mungkin ingin melihat kode C# yang dihasilkan. Anda dapat menentukan untuk menggunakan perilaku lama ini dengan konfigurasi berikut:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.xml.serialization>
    <xmlSerializer tempFilesLocation='e:\temp\XmlSerializerBug' useLegacySerializerGeneration="true" />
  </system.xml.serialization>
  <system.diagnostics>
    <switches>
      <add name="XmlSerialization.Compilation" value="1" />
    </switches>
  </system.diagnostics>
</configuration>

Jika Anda mengalami masalah kompatibilitas, seperti XmlSerializer gagal melakukan serialisasi kelas turunan dengan penimpaan baru non-publik, Anda dapat beralih kembali ke perilaku lama XMLSerializer dengan menggunakan konfigurasi berikut:

<configuration>
  <appSettings>
    <add key="System:Xml:Serialization:UseLegacySerializerGeneration" value="true" />
  </appSettings>
</configuration>

Sebagai alternatif dari konfigurasi di atas, Anda dapat menggunakan konfigurasi berikut pada mesin yang menjalankan .NET Framework versi 4.5 atau yang lebih baru:

<configuration>
  <system.xml.serialization>
    <xmlSerializer useLegacySerializerGeneration="true"/>
  </system.xml.serialization>
</configuration>

Catatan

Parameter <xmlSerializer useLegacySerializerGeneration="true"/> hanya berfungsi pada komputer yang menjalankan .NET Framework 4.5 atau versi yang lebih baru. Pendekatan appSettings di atas berfungsi pada semua versi .NET Framework.

Lihat juga