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 menserialisasikan jenis data. Serializer ini mendukung jenis berikut:

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

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

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

  • Jenis yang mengimplementasikan IXmlSerializable antarmuka.

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

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

DataContractSerializer, 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 XmlSerializer kelas . Kelas XmlSerializer ini tidak unik untuk WCF. Ini adalah mesin serialisasi yang sama dengan yang digunakan ASP.NET layanan Web. Kelas ini XmlSerializer mendukung serangkaian jenis yang jauh lebih sempit daripada DataContractSerializer kelas, tetapi memungkinkan kontrol yang jauh lebih besar atas XML yang dihasilkan dan mendukung lebih banyak standar bahasa definisi Skema XML (XSD). Ini juga tidak memerlukan atribut deklaratif pada jenis yang dapat diserialisasikan. Untuk informasi selengkapnya, lihat topik Serialisasi XML dalam 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 maka dipilih.

Beralih ke XmlSerializer

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

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

  • Ketika kontrol yang tepat atas XML yang muncul dalam pesan penting, tetapi dokumen Web Services Description Language (WSDL) tidak tersedia, misalnya, saat membuat layanan dengan jenis yang harus mematuhi skema standar tertentu yang diterbitkan yang tidak kompatibel dengan DataContractSerializer.

  • Saat membuat layanan yang mengikuti standar Encoding SOAP warisan.

Dalam kasus ini dan lainnya, Anda dapat beralih secara manual ke XmlSerializer kelas dengan menerapkan XmlSerializerFormatAttribute atribut 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

Nota

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

Misalnya, DataContractSerializer kelas hanya menserialisasikan anggota yang ditandai dengan DataMemberAttribute atribut saat menserialisasikan jenis kontrak data. Kelas ini XmlSerializer melakukan serialisasi pada 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 jenis secara tidak sengaja digunakan dalam kontrak layanan di mana kelas XmlSerializer dipilih, anggota creditCardNumber diserialisasikan, yang mungkin tidak dimaksudkan.

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

Serializer yang digunakan untuk layanan adalah 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 XmlSerializer kelas . Pertama, sangat disarankan agar setiap aplikasi WCF yang menggunakan kelas ditandatangani XmlSerializer dengan kunci yang dilindungi dari pengungkapan. Rekomendasi ini berlaku baik ketika pengalihan manual ke XmlSerializer terjadi maupun ketika pengalihan otomatis terjadi (dengan Svcutil.exe, Tambahkan Referensi Layanan, atau alat serupa). Ini karena XmlSerializer mesin serialisasi 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 diharapkan dari rakitan serialisasi yang telah dibuat sebelumnya yang ditempatkan di folder aplikasi atau cache 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 terkait dengan akses tulis ke folder sementara sistem. Mesin XmlSerializer serialisasi membuat dan menggunakan rakitan serialisasi sementara dalam folder ini. Anda harus sadar bahwa setiap proses dengan akses tulis ke folder temporer dapat menimpa rakitan serialisasi ini dengan kode yang berbahaya.

Aturan untuk dukungan XmlSerializer

Anda tidak dapat langsung menerapkan XmlSerializeratribut -kompatibel ke parameter operasi kontrak atau mengembalikan nilai. Namun, mereka dapat diterapkan ke pesan yang ditik (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 pada anggota pesan bertipe, atribut ini menggantikan properti yang bertentangan pada atribut pesan bertipe. Misalnya, dalam kode berikut, ElementName ambil 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.

Nota

Dalam hal ini, XmlSerializer melemparkan pengecualian berikut, yang dirilis sebelum WCF: "Elemen yang dideklarasikan di tingkat atas skema tidak boleh memiliki maxOccurs> 1. Berikan elemen pembungkus untuk 'more' dengan menggunakan XmlArray atau XmlArrayItem alih-alih XmlElementAttribute, atau dengan menggunakan gaya parameter yang dibungkus.

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

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

Jenis yang Mengimplementasikan Antarmuka IXmlSerializable

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

Peringatan

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

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

  • Jenis konten menggunakan metode penyedia skema yang ditentukan oleh XmlSchemaProviderAttribute atribut . Metode ini tidak mengembalikan null, dan properti IsAny pada atribut dibiarkan dengan nilai defaultnya 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 IsAny properti pada XmlSchemaProviderAttribute atribut 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 ditentukan, metode harus mengembalikan null.

  • Jenis lama DataSet adalah jenis IXmlSerializable yang tidak ditandai dengan atribut XmlSchemaProviderAttribute. Sebaliknya, mereka mengandalkan GetSchema metode untuk pembuatan skema. Pola ini digunakan untuk jenis DataSet dan himpunan data berjenis ini menurunkan kelas dalam versi .NET Framework yang lebih lama, tetapi sekarang ini tidak lagi digunakan dan didukung hanya untuk alasan kompatibilitas warisan. Jangan sepenuhnya mengandalkan pola ini dan selalu terapkan XmlSchemaProviderAttribute ke jenis IXmlSerializable Anda.

Tipe Isi IXmlSerializable

Saat menserialisasikan anggota data dari sebuah tipe yang mengimplementasikan IXmlSerializable dan merupakan tipe konten seperti yang telah didefinisikan sebelumnya, serializer menulis elemen pembungkus untuk anggota data dan kemudian meneruskan kontrol ke metode WriteXml. Implementasi WriteXml dapat menulis XML apa pun, termasuk menambahkan atribut ke elemen pembungkus. Setelah WriteXml selesai, serializer menutup elemen .

Saat mendeserialisasi anggota data dari jenis yang mengimplementasikan IXmlSerializable dan merupakan tipe konten seperti yang telah didefinisikan sebelumnya, deserializer menempatkan 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 Anda ReadXml menangani kasus di mana elemen kosong. Selain itu, implementasi Anda ReadXml tidak boleh mengandalkan elemen pembungkus yang dinamai dengan cara tertentu. Nama yang dipilih oleh serializer dapat berbeda-beda.

Diizinkan untuk menetapkan IXmlSerializable jenis konten secara polimorfik, misalnya, untuk anggota data jenis Object. Ini juga diizinkan untuk instans jenis menjadi null. Akhirnya, jenis IXmlSerializable dapat digunakan dengan preservasi grafik objek yang diaktifkan dan dengan NetDataContractSerializer. Semua fitur ini memerlukan serializer WCF untuk melampirkan atribut tertentu pada elemen pembungkus ("nil" dan "type" di namespace XML Schema Instance dan "Id", "Ref", "Type" dan "Assembly" di namespace khusus WCF).

Atribut untuk Diabaikan saat Menerapkan ReadXml

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

Pertimbangan Skema untuk Tipe Konten IXmlSerializable

Jika skema dan tipe konten IXmlSerializable diekspor, metode penyedia skema akan dipanggil. XmlSchemaSet diteruskan ke metode penyedia skema. Metode ini dapat menambahkan skema 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 harus menentukan apakah XmlSchema dengan namespace yang sesuai sudah ada dalam set. Jika ya, metode penyedia skema harus menambahkan item baru ke XmlSchema. Jika tidak, harus membuat instans XmlSchema baru. Ini penting jika array jenis IXmlSerializable sedang digunakan. Misalnya, jika Anda memiliki IXmlSerializable jenis yang diekspor sebagai tipe "A" dalam namespace "B", ada kemungkinan bahwa saat metode penyedia skema dipanggil, set skema tersebut sudah berisi skema untuk "B" guna menampung tipe "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 yang diberikan IXmlSerializable . Nama yang memenuhi syarat ini juga berfungsi sebagai nama kontrak data dan namespace untuk tipe tersebut. Diizinkan untuk mengembalikan jenis yang tidak ada dalam set skema segera ketika metode penyedia skema kembali. Namun, diharapkan bahwa pada saat semua tipe terkait diekspor (metode tersebut dipanggil untuk seluruh tipe terkait pada Export, dan properti XsdDataContractExporter diakses), tipe tersebut sudah ada dalam kumpulan skema. Mengakses properti Schemas sebelum semua panggilan Export yang relevan dilakukan dapat mengakibatkan XmlSchemaException. Untuk informasi selengkapnya tentang proses ekspor, lihat Mengekspor Skema dari Kelas.

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

Selain itu, deklarasi elemen global diekspor untuk jenis tersebut. Jika jenis tidak memiliki XmlRootAttribute atribut 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 XmlRootAttribute atribut yang diterapkan padanya, deklarasi elemen global diekspor menggunakan properti berikut: ElementName, Namespace dan IsNullable . Default yang diterapkan dengan XmlRootAttribute adalah nama kontrak data, namespace kosong, dan "nillable" adalah true.

Aturan deklarasi elemen global yang sama berlaku untuk jenis himpunan data warisan. Perhatikan bahwa XmlRootAttribute tidak dapat menggantikan deklarasi elemen global yang ditambahkan melalui kode kustom, baik yang ditambahkan ke XmlSchemaSet menggunakan metode penyedia skema, maupun melalui GetSchema untuk jenis himpunan data warisan.

Jenis Elemen IXmlSerializable

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

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

  • Implementasi WriteXml diharapkan untuk menulis tepat satu elemen (yang tentu saja dapat berisi beberapa elemen turunan). Seharusnya tidak menulis atribut di luar elemen tunggal ini, beberapa elemen saudara kandung atau konten campuran. Elemen mungkin kosong.

  • Implementasi ReadXml tidak boleh membaca elemen pembungkus. Diharapkan untuk membaca elemen yang dihasilkan oleh WriteXml.

  • Saat menserialisasikan jenis elemen secara teratur (misalnya, sebagai anggota data dalam kontrak data), serializer menghasilkan elemen pembungkus sebelum memanggil WriteXml, seperti halnya jenis konten. Namun, ketika menserialisasikan jenis elemen pada level teratas, serializer biasanya tidak mengeluarkan elemen pembungkus di sekitar elemen yang ditulis oleh WriteXml, kecuali nama akar dan ruang nama ditentukan secara eksplisit saat membangun serializer dalam 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 diserialisasikan tidak dapat null dan tidak dapat ditetapkan secara polimorfik. Selain itu, pelestarian grafik objek tidak dapat diaktifkan dan NetDataContractSerializer tidak dapat digunakan.

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

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

Perbedaan dari XmlSerializer

Antarmuka IXmlSerializable serta atribut XmlSchemaProviderAttribute dan XmlRootAttribute juga dipahami oleh XmlSerializer. Namun, ada beberapa perbedaan dalam bagaimana ini diperlakukan dalam model kontrak data. Perbedaan penting dirangkum dalam daftar berikut:

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

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

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

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

Mengimpor Skema IXmlSerializable

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

  • Skema yang dihasilkan mungkin merupakan 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 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 IXmlSerializable jenis. Mode impor ini tidak diaktifkan secara default tetapi dapat dengan mudah dihidupkan, misalnya dengan menggunakan sakelar baris perintah /importXmlTypes pada ServiceModel Metadata Utility Tool (Svcutil.exe). Ini dijelaskan secara rinci dalam Skema Mengimpor untuk Membuat Kelas. Perhatikan bahwa Anda harus bekerja langsung dengan XML untuk instans jenis Anda. Anda juga dapat mempertimbangkan untuk menggunakan teknologi serialisasi berbeda yang mendukung skema yang lebih luas - lihat topik tentang menggunakan XmlSerializer.

  • Anda mungkin ingin menggunakan kembali jenis yang ada IXmlSerializable 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 /reference sakelar pada svcutil.exe, yang menentukan rakitan yang berisi jenis yang akan digunakan kembali.

Perilaku Warisan XmlSerializer

Di .NET Framework 4.0 dan yang lebih lama, XmlSerializer menghasilkan rakitan serialisasi sementara dengan menulis kode C# ke file. File kemudian dikompilasi ke dalam kode hasil kompilasi. Perilaku ini memiliki beberapa konsekuensi yang tidak diinginkan seperti memperlambat waktu startup untuk serializer. Dalam .NET Framework 4.5, perilaku ini diubah untuk menghasilkan rakitan tanpa memerlukan penggunaan pengkompilasi. Beberapa pengembang mungkin ingin melihat kode C# yang dihasilkan. Anda dapat menentukan untuk menggunakan perilaku warisan 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 men-serialisasi kelas turunan dengan override baru yang non-publik, Anda dapat beralih ke perilaku lama dengan menggunakan konfigurasi berikut:

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

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

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

Nota

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

Lihat juga