Bagikan melalui


Serialisasi JSON mandiri menggunakan DataContractJsonSerializer

Catatan

Artikel ini tentang DataContractJsonSerializer. Untuk sebagian besar skenario yang melibatkan serialisasi dan deserialisasi JSON, kami merekomendasikan API di namespace System.Text.Json.

JSON (JavaScript Object Notation) adalah format data yang dirancang khusus untuk digunakan oleh kode JavaScript yang berjalan di halaman Web di dalam browser. JSON adalah format data default yang digunakan oleh layanan AJAX ASP.NET yang dibuat di Windows Communication Foundation (WCF).

Format ini juga dapat digunakan saat membuat layanan AJAX tanpa mengintegrasikan dengan ASP.NET - dalam kasus ini, XML merupakan default tetapi JSON dapat dipilih.

Terakhir, jika Anda memerlukan dukungan JSON tetapi tidak membuat layanan AJAX, DataContractJsonSerializer memungkinkan untuk secara langsung membuat serialisasi objek .NET ke dalam data JSON dan untuk mendeserialisasi data tersebut kembali ke dalam instans jenis .NET. Untuk deskripsi tentang cara melakukannya, lihat Cara: Membuat Serialisasi dan Deserialisasi Data JSON.

Saat bekerja dengan JSON, jenis .NET yang sama didukung, dengan beberapa pengecualian, seperti yang didukung oleh DataContractSerializer. Untuk daftar jenis yang didukung, lihat Jenis yang Didukung oleh Serializer Kontrak Data. Jenis yang didukung ini termasuk jenis yang paling primitif, sebagian besar jenis array dan koleksi, serta jenis kompleks yang menggunakan DataContractAttribute dan DataMemberAttribute.

Memetakan jenis .NET ke jenis JSON

Tabel berikut menunjukkan korespondensi antara jenis .NET dan jenis JSON/JavaScript saat dipetakan oleh prosedur serialisasi dan deserialisasi.

Jenis .NET JSON/JavaScript Catatan
Semua jenis numerik, misalnya Int32, Decimal atau Double Angka Nilai khusus seperti Double.NaN, Double.PositiveInfinity dan Double.NegativeInfinity tidak didukung dan menghasilkan JSON yang tidak valid.
Enum Angka Lihat "Enumerasi dan JSON" nanti di artikel ini.
Boolean Boolean
String, Char String
TimeSpan, , GuidUri String Format jenis ini di JSON sama seperti dalam XML (pada dasarnya, rentang waktu dalam format Durasi ISO 8601, GUID dalam format "12345678-ABCD-ABCD-ABCD-1234567890AB", dan URI dalam bentuk string alaminya seperti "http://www.example.com"). Untuk informasi yang tepat, lihat Referensi Skema Kontrak Data.
XmlQualifiedName String Formatnya adalah "name:namespace" (apa pun sebelum titik dua pertama adalah nama). Baik nama ataupun namespace layanan bisa hilang. Jika tidak ada namespace layanan, titik dua juga dapat dihilangkan.
Array dari jenis Byte Array angka Setiap angka menunjukkan nilai satu byte.
DateTime TanggalWaktu atau String Lihat Dates/Times dan JSON nanti di artikel ini.
DateTimeOffset Jenis kompleks Lihat Dates/Times dan JSON nanti di artikel ini.
Jenis XML dan ADO.NET (XmlElement,

XElement. Array dari XmlNode,

ISerializable,

DataSet).
String Lihat bagian Tipe XML dan JSON di artikel ini.
DBNull Jenis kompleks kosong --
Koleksi, kamus, dan array Array Lihat bagian Koleksi, Kamus, dan Array dari topik ini.
Jenis kompleks (dengan DataContractAttribute atau SerializableAttribute diterapkan) Jenis kompleks Anggota data menjadi anggota dari jenis kompleks JavaScript.
Jenis kompleks yang mengimplementasikan antarmuka ISerializable) Jenis kompleks Sama seperti jenis kompleks lainnya tetapi beberapa ISerializable jenis tidak didukung - lihat Dukungan ISerializable.
nilai Null untuk semua jenis Null Jenis nilai yang dapat diubah ke null juga didukung dan dipetakan ke JSON dengan cara yang sama seperti jenis nilai yang tidak dapat diubah ke null.

Enumerasi dan JSON

Nilai anggota enumerasi diperlakukan sebagai angka di JSON, yang mana berbeda dari cara nilai tersebut diperlakukan dalam kontrak data, tempat nilai tersebut disertakan sebagai nama anggota. Untuk informasi selengkapnya tentang perlakuan kontrak data, lihat Jenis Enumerasi dalam Kontrak Data.

  • Misalnya, jika Anda memiliki public enum Color {red, green, blue, yellow, pink}, yang melakukan serialisasi yellow menghasilkan angka 3 dan bukan string "kuning".

  • Semua anggota enum dapat diserialisasikan. Atribut EnumMemberAttribute dan NonSerializedAttribute diabaikan jika digunakan.

  • Dimungkinkan untuk mendeserialisasi nilai enum yang tidak ada - misalnya, nilai 87 dapat dideserialisasi ke enumerasi Warna sebelumnya meskipun tidak ada nama warna yang ditentukan yang sesuai.

  • Bendera enum tidak istimewa dan diperlakukan sama dengan enum lainnya.

Tanggal/waktu dan JSON

Format JSON tidak secara langsung mendukung tanggal dan waktu. Namun, mereka sangat umum digunakan dan AJAX ASP.NET memberikan dukungan khusus untuk jenis ini. Saat menggunakan proksi AJAX ASP.NET, jenis DateTime di .NET sepenuhnya sesuai dengan jenis DateTime di JavaScript.

  • Saat tidak menggunakan ASP.NET, jenis DateTime diwakili dalam JSON sebagai string dengan format khusus yang dijelaskan di bagian Informasi Tingkat Lanjut dari topik ini.

  • DateTimeOffset diwakili dalam JSON sebagai jenis kompleks: {"DateTime":dateTime,"OffsetMinutes":offsetMinutes}. Anggota offsetMinutes adalah offset waktu lokal dari Waktu Greenwich (GMT), kini disebut sebagai Waktu Universal Terkoordinasi (UTC), yang terkait dengan lokasi peristiwa menarik. Anggota dateTime mewakili instans pada waktunya ketika peristiwa menarik terjadi (sekali lagi, anggota tersebut menjadi DateTime di JavaScript ketika AJAX ASP.NET sedang digunakan dan string tidak digunakan). Pada serialisasi, anggota dateTime selalu diserialisasikan dalam GMT. Jadi, jika menggambarkan pukul 03.00 waktu New York, dateTime memiliki komponen waktu 08.00 dan offsetMinutes adalah 300 (minus 300 menit atau 5 jam dari GMT).

    Catatan

    Objek DateTime dan DateTimeOffset, ketika diserialisasikan ke JSON, hanya mempertahankan informasi ke presisi milidetik. Nilai sub-milidetik (mikro/nanodetik) hilang selama serialisasi.

Jenis XML dan JSON

Jenis XML menjadi string JSON.

  • Misalnya, jika anggota data "q" dari jenis XElement berisi <abc/>, JSON adalah {"q":"<abc/>"}.

  • Ada beberapa aturan khusus yang menentukan bagaimana XML dibungkus - untuk informasi selengkapnya, lihat bagian Informasi Tingkat Lanjut nanti di artikel ini.

  • Jika Anda menggunakan AJAX ASP.NET dan tidak ingin menggunakan string di JavaScript, tetapi ingin XML DOM sebagai gantinya, atur properti ResponseFormat ke XML pada properti WebGetAttribute atau ResponseFormat ke XML pada WebInvokeAttribute.

Koleksi, kamus, dan array

Semua koleksi, kamus, dan array diwakili dalam JSON sebagai array.

  • Kustomisasi apa pun yang menggunakan CollectionDataContractAttribute diabaikan dalam representasi JSON.

  • Kamus bukanlah cara untuk bekerja langsung dengan JSON. String < kamus, >objek mungkin tidak didukung dengan cara yang sama dalam WCF seperti yang diharapkan dari bekerja dengan teknologi JSON lainnya. Misalnya, jika "abc" dipetakan ke "xyz" dan "def" dipetakan ke 42 dalam kamus, representasi JSON bukan {"abc":"xyz","def":42} tetapi [{"Key":"abc","Value":"xyz"},{"Key":"def","Value":42}] sebagai gantinya.

  • Jika Anda ingin bekerja dengan JSON secara langsung (mengakses kunci dan nilai secara dinamis, tanpa menentukan kontrak yang kaku sebelumnya), Anda memiliki beberapa opsi:

    • Pertimbangkan untuk menggunakan sampel Serialisasi JSON (AJAX) yang berjenis lemah.

    • Pertimbangkan untuk menggunakan antarmuka ISerializable dan konstruktor deserialisasi - kedua mekanisme ini memungkinkan Anda mengakses pasangan kunci/nilai JSON pada serialisasi dan deserialisasi masing-masing, tetapi tidak berfungsi dalam skenario kepercayaan parsial.

    • Pertimbangkan untuk bekerja dengan Pemetaan Antara JSON dan XML sebagai ganti menggunakan serializer.

    • Polimorfisme dalam konteks serialisasi mengacu pada kemampuan untuk menserialisasikan jenis turunan di mana jenis dasarnya diharapkan. Terdapat aturan khusus JSON tertentu saat menggunakan koleksi secara polimorfik, misalnya saat menetapkan koleksi ke Object. Masalah ini lebih lengkap dibahas di bagian Informasi Tingkat Lanjut nanti di artikel ini.

Detail Tambahan

Urutan Anggota Data

Urutan anggota data tidak penting saat menggunakan JSON. Secara khusus, bahkan jika Order diatur, data JSON masih dapat dideserialisasi dalam urutan apa pun.

Jenis JSON

Jenis JSON tidak harus cocok dengan tabel sebelumnya pada deserialisasi. Misalnya, Int biasanya memetakan ke nomor JSON, tetapi juga dapat berhasil dideserialisasi dari string JSON selama string tersebut berisi angka yang valid. Artinya, kedua {"q":42} dan {"q":"42"} valid jika ada anggota data Int yang disebut "q".

Polimorfisme

Serialisasi polimorfik terdiri dari kemampuan untuk membuat serialisasi jenis turunan di mana jenis dasarnya diharapkan. Serialisasi polimorfik didukung untuk serialisasi JSON oleh WCF sebanding dengan cara serialisasi XML yang didukung. Misalnya, Anda dapat menserialisasikan MyDerivedType tempat MyBaseType diharapkan, atau menserialisasikan Int tempat Object diharapkan.

Informasi jenis mungkin hilang saat mendeserialisasi jenis turunan jika jenis dasar diharapkan, kecuali Anda mendeserialisasi jenis kompleks. Misalnya, jika Uri diserialisasikan tempat Object diharapkan, diserialisasi menghasilkan string JSON. Jika string ini kemudian dideserialisasi kembali ke Object, .NET String dikembalikan. Deserializer tidak tahu bahwa string awalnya berjenis Uri. Umumnya, ketika mengharapkan Object, semua string JSON dideserialisasi sebagai string .NET, dan semua array JSON digunakan untuk membuat serialisasi koleksi, kamus, dan array .NET, dideserialisasi sebagai Array .NET dari jenis Object, terlepas dari jenis asli yang sebenarnya. Boolean JSON memetakan ke Boolean .NET. Namun ketika mengharapkan Object, nomor JSON dideserialisasi sebagai Int32, Decimal atau Double .NET, tempat jenis yang paling tepat secara otomatis dipilih.

Saat deserialisasi ke dalam jenis antarmuka, DataContractJsonSerializer mendeserialisasi seakan-akan jenis yang dinyatakan adalah objek.

Saat bekerja dengan jenis dasar dan turunan Anda sendiri, menggunakan KnownTypeAttribute, ServiceKnownTypeAttribute atau mekanisme yang setara biasanya diperlukan. Misalnya, jika Anda memiliki operasi yang memiliki nilai pengembalian Animal dan benar-benar mengembalikan instans Cat (berasal dari Animal), Anda harus menerapkan KnownTypeAttribute, ke jenis Animal atau ServiceKnownTypeAttribute ke operasi dan menentukan jenis Cat dalam atribut ini. Untuk informasi selengkapnya, lihat Jenis yang Diketahui Kontrak Data.

Untuk detail cara kerja serialisasi polimorfik dan diskusi tentang beberapa batasan yang harus dihormati saat menggunakannya, lihat bagian Informasi Tingkat Lanjut nanti di artikel ini.

Penerapan versi

Fitur penerapan versi kontrak data, termasuk antarmuka IExtensibleDataObject, didukung penuh di JSON. Selain itu, dalam kebanyakan kasus dimungkinkan untuk mendeserialisasi jenis dalam satu format (misalnya, XML) dan kemudian menserialisasikannya ke format lain (misalnya, JSON) dan masih mempertahankan data di IExtensibleDataObject. Untuk informasi selengkapnya, lihat Kontrak Data yang Kompatibel Dengan Penerusan. Ingatlah bahwa JSON tidak diurutkan sehingga urutan informasi apa pun hilang. Selain itu, JSON tidak mendukung beberapa pasangan kunci/nilai dengan nama kunci yang sama. Akhirnya, semua operasi pada IExtensibleDataObject polimorfik secara inheren - yang merupakan jenis turunannya ditetapkan ke Object, jenis dasar untuk semua jenis.

JSON dalam URL

Saat menggunakan titik akhir AJAX ASP.NET dengan kata kerja HTTP GET (menggunakan atribut WebGetAttribute), parameter masuk muncul di URL permintaan sebagai ganti isi pesan. JSON didukung bahkan di URL permintaan, jadi jika Anda memiliki operasi yang mengambil Int yang disebut "angka" dan jenis kompleks Person yang disebut "p", URL mungkin menyerupai URL berikut.

http://example.com/myservice.svc/MyOperation?number=7&p={"name":"John","age":42}

Jika Anda menggunakan kontrol dan proksi Manajer Skrip AJAX ASP.NET untuk memanggil layanan tersebut, URL ini secara otomatis dihasilkan oleh proksi dan tidak terlihat. JSON tidak dapat digunakan dalam URL pada titik akhir AJAX non-ASP.NET.

Informasi Tingkat Lanjut

Dukungan ISerializable

Jenis ISerializable yang Didukung dan Tidak Didukung

Secara umum, jenis yang mengimplementasikan antarmuka ISerializable didukung penuh saat menserialisasi/mendeserialisasi JSON. Namun, beberapa jenis ini (termasuk beberapa jenis .NET Framework) diimplementasikan sedimikian rupa sehingga aspek serialisasi khusus JSON menyebabkannya tidak mendeserialisasi dengan benar:

  • Dengan ISerializable, jenis anggota data individual tidak pernah diketahui sebelumnya. Hal ini menyebabkan situasi polimorfik yang mirip dengan jenis deserialisasi ke dalam objek. Seperti disebutkan sebelumnya, hal ini dapat menyebabkan hilangnya informasi jenis di JSON. Misalnya, jenis yang menserialisasikan enum dalam penerapan ISerializablenya dan upaya untuk mendeserialisasi kembali langsung ke enum (tanpa transmisi yang tepat) gagal, karena enum diserialisasi menggunakan angka dalam angka JSON dan JSON mendeserialisasi ke dalam jenis numerik .NET bawaan (Int32, Desimal atau Ganda). Jadi faktanya bahwa angka yang digunakan untuk menjadi nilai enum hilang.

  • Jenis ISerializable yang bergantung pada urutan deserialisasi tertentu dalam konstruktor deserialisasinya mungkin juga gagal mendeserialisasi beberapa data JSON, karena sebagian besar serializer JSON tidak menjamin urutan tertentu.

Jenis Pabrik

Meskipun antarmuka IObjectReference didukung di JSON secara umum, jenis apa pun yang memerlukan fitur "jenis pabrik" (mengembalikan instans dengan jenis yang berbeda dari GetRealObject(StreamingContext) kemudian jenis yang mengimplementasikan antarmuka) tidak didukung.

DateTime Wire Format

Nilai DateTime muncul sebagai string JSON dalam bentuk "/Date(700000+0500)/", tempat angka pertama (700000 dalam contoh yang disediakan) adalah jumlah milidetik di zona waktu GMT, waktu reguler (non daylight saving) sejak tengah malam, 1 Januari 1970. Angka mungkin negatif untuk mewakili waktu sebelumnya. Bagian yang terdiri dari "+0500" dalam contoh bersifat opsional dan menunjukkan bahwa waktu tersebut adalah jenis Local - yaitu, harus dikonversi ke zona waktu lokal pada deserialisasi. Jika tidak ada, waktu tersebut dideserialisasi sebagai Utc. Angka aktual ("0500" dalam contoh ini) dan tandanya (+ atau -) diabaikan.

Ketika serialisasi waktu DateTime, Local dan Unspecified ditulis dengan offset, dan Utc ditulis tanpa offset.

Kode JavaScript klien AJAX ASP.NET secara otomatis mengonversi string tersebut menjadi instans DateTime JavaScript. Jika ada string lain yang memiliki bentuk serupa yang bukan dari DateTime jenis di .NET, string tersebut juga dikonversi.

Konversi hanya terjadi jika karakter "/" diloloskan (yaitu, JSON terlihat seperti "\/Date(700000+0500)\/"), dan karena alasan ini encoder JSON WCF (diaktifkan oleh WebHttpBinding) selalu meloloskan dari karakter "/".

XML dalam String JSON

XmlElement

XmlElement diserialisasikan apa adanya, tanpa pembungkusan. Misalnya, anggota data "x" dari XmlElement jenis yang berisi <abc/> diwakili sebagai berikut:

{"x":"<abc/>"}

Array XmlNode

Objek Array dari XmlNode jenis dibungkus dalam elemen yang disebut ArrayOfXmlNode di namespace layanan kontrak data standar untuk jenis tersebut. Jika "x" adalah array yang berisi node atribut "N" di namespace layanan "ns" yang berisi "nilai" dan node elemen kosong "M", representasinya adalah sebagai berikut.

{"x":"<ArrayOfXmlNode xmlns=\"http://schemas.datacontract.org/2004/07/System.Xml\" a:N=\"value\" xmlns:a=\"ns\"><M/></ArrayOfXmlNode>"}

Atribut pada namespace layanan yang kosong di awal array XmlNode (sebelum elemen lain) tidak didukung.

Jenis IXmlSerializable termasuk XElement dan DataSet

Jenis ISerializable dibagi menjadi "jenis konten", "jenis DataSet" dan "jenis elemen". Untuk definisi jenis ini, lihat Jenis XML dan ADO.NET dalam Kontrak Data.

Jenis "Konten" dan "DataSet" diserialisasikan mirip dengan objek Array dari XmlNode yang dibahas di bagian sebelumnya. Jenis tersebut dibungkus dalam elemen yang nama dan namespace layanannya sesuai dengan nama kontrak data dan namespace layanan jenis yang dimaksud.

Jenis "Elemen" seperti XElement diserialisasikan apa adanya, mirip XmlElement dengan yang dibahas sebelumnya dalam artikel ini.

Polimorfisme

Mempertahankan Informasi Jenis

Seperti yang dinyatakan sebelumnya, polimorfisme didukung di JSON dengan beberapa batasan. JavaScript merupakan bahasa yang berjenis lemah dan identitas jenis yang biasanya bukan sebuah masalah. Namun, saat menggunakan JSON untuk berkomunikasi antara sistem berjenis kuat (.NET) dan sistem berjenis lemah (JavaScript), berguna untuk mempertahankan identitas jenis. Misalnya, jenis dengan nama kontrak data "Square" dan "Circle" berasal dari jenis dengan nama kontrak data "Shape". Jika "Circle" dikirim dari .NET ke JavaScript dan kemudian dikembalikan ke metode .NET yang mengharapkan "Shape", berguna bagi sisi .NET untuk mengetahui bahwa objek yang dimaksud awalnya adalah "Circle" - jika tidak, informasi apa pun yang khusus untuk jenis turunan (misalnya, anggota data "radius" pada "Circle") mungkin hilang.

Untuk mempertahankan identitas jenis, saat menserialisasikan jenis kompleks ke JSON, "type hint" dapat ditambahkan, dan deserializer mengenali petunjuk dan bertindak dengan tepat. "type hint" adalah pasangan kunci/nilai JSON dengan nama kunci "__type" (dua garis bawah diikuti dengan kata "type"). Nilai tersebut merupakan string JSON dari bentuk "DataContractName:DataContractNamespace" (apa pun hingga titik dua pertama adalah nama). Dengan menggunakan contoh sebelumnya, "Circle" dapat diserialisasikan sebagai berikut.

{"__type":"Circle:http://example.com/myNamespace","x":50,"y":70,"radius":10}

Petunjuk jenis sangat mirip dengan atribut xsi:type yang ditentukan oleh standar Instans Skema XML dan digunakan saat membuat serialisasi/deserialisasi XML.

Anggota data yang disebut "__type" dilarang karena potensi konflik dengan petunjuk jenis.

Mengurangi Ukuran Type Hints

Untuk mengurangi ukuran pesan JSON, awalan namespace layanan kontrak data default (http://schemas.datacontract.org/2004/07/) diganti dengan karakter "#". (Untuk membuat penggantian ini dapat dibalik, aturan pelolosan digunakan: jika namespace layanan dimulai dengan karakter "#" atau "\", karakter tersebut ditambahkan dengan karakter "\" tambahan). Dengan demikian, jika "Circle" adalah jenis di namespace layanan .NET "MyApp.Shapes", namespace layanan kontrak data defaultnya adalah http://schemas.datacontract.org/2004/07/MyApp. Bentuk dan representasi JSON adalah sebagai berikut.

{"__type":"Circle:#MyApp.Shapes","x":50,"y":70,"radius":10}

Nama yang dipotong (#MyApp.Shapes) dan nama lengkap (http://schemas.datacontract.org/2004/07/MyApp.Shapes), keduanya dipahami pada deserialisasi.

Posisi Petunjuk Jenis di Objek JSON

Perhatikan bahwa petunjuk jenis harus muncul terlebih dahulu di representasi JSON. Petunjuk jenis adalah satu-satunya kasus di mana urutan pasangan kunci/nilai penting dalam pemrosesan JSON. Misalnya, berikut ini bukan cara yang valid untuk menentukan petunjuk jenis.

{"x":50,"y":70,"radius":10,"__type":"Circle:#MyApp.Shapes"}

Kedua DataContractJsonSerializer digunakan oleh klien WCF dan ASP.NET AJAX selalu memancarkan petunjuk jenis terlebih dahulu.

Petunjuk Jenis Hanya Berlaku untuk Jenis Kompleks

Tidak ada cara untuk memancarkan petunjuk jenis untuk jenis yang tidak kompleks. Misalnya, jika operasi memiliki jenis pengembalian Object tetapi mengembalikan Circle, representasi JSON dapat seperti yang ditunjukkan sebelumnya dan informasi jenis dipertahankan. Namun, jika Uri dikembalikan, representasi JSON adalah string dan faktanya bahwa string yang digunakan untuk mewakili Uri hilang. Hal ini tidak hanya berlaku untuk jenis primitif tetapi juga untuk koleksi dan array.

Kapan Petunjuk Jenis Dikeluarkan

Petunjuk jenis dapat meningkatkan ukuran pesan secara signifikan (salah satu cara untuk menguranginya adalah dengan menggunakan namespace layanan kontrak data yang lebih pendek jika memungkinkan). Oleh karena itu, aturan berikut mengatur apakah petunjuk jenis dipancarkan:

  • Saat menggunakan AJAX ASP.NET, petunjuk jenis selalu dipancarkan jika memungkinkan, bahkan jika tidak ada penugasan dasar/turunan - misalnya, bahkan jika Circle ditetapkan ke Circle. (Hal ini diperlukan untuk sepenuhnya memungkinkan proses panggilan dari lingkungan JSON yang berjenis lemah ke lingkungan .NET yang berjenis kuat tanpa kehilangan informasi yang mengejutkan.)

  • Saat menggunakan layanan AJAX tanpa integrasi ASP.NET, petunjuk jenis hanya dipancarkan saat ada penugasan dasar/turunan - yaitu, dipancarkan saat Circle ditetapkan ke Shape atau Object tetapi tidak saat ditetapkan ke Circle. Layanan ini memberikan informasi minimum yang diperlukan untuk mengimplementasikan klien JavaScript dengan benar, sehingga meningkatkan performa, tetapi tidak melindungi dari kehilangan informasi jenis dalam klien yang salah dirancang. Hindari sama sekali penugasan dasar/turunan di server jika Anda ingin menghindari berurusan dengan masalah ini pada klien.

  • Saat menggunakan jenis DataContractSerializer, parameter konstruktor alwaysEmitTypeInformation memungkinkan Anda memilih antara dua mode sebelumnya, dengan defaultnya adalah "false" (hanya mengeluarkan petunjuk jenis saat diperlukan).

Menduplikat Nama Anggota Data

Informasi jenis turunan hadir dalam objek JSON yang sama, bersama dengan informasi jenis dasar, dan dapat terjadi dalam urutan apa pun. Misalnya, Shape dapat direpresentasikan sebagai berikut.

{"__type":"Shape:#MyApp.Shapes","x":50,"y":70}

Sedangkan Circle dapat direpresentasikan sebagai berikut.

{"__type":"Circle:#MyApp.Shapes","x":50, "radius":10,"y":70}

Jika jenis Shape dasar juga berisi anggota data yang disebut "radius", hal ini menyebabkan tabrakan pada kedua serialisasi (karena objek JSON tidak dapat memiliki nama kunci berulang) dan deserialisasi (karena tidak jelas apakah "radius" mengacu pada Shape.radius atau Circle.radius). Oleh karena itu, sementara konsep "property hiding" (anggota data dengan nama yang sama berdasarkan dan kelas turunan) umumnya tidak direkomendasikan dalam kelas kontrak data, konsep tersebut sebenarnya dilarang dalam kasus JSON.

Jenis Polimorfisme dan IXmlSerializable

Jenis IXmlSerializable dapat secara polimorfik ditetapkan satu sama lain seperti biasa selama persyaratan Jenis yang Diketahui terpenuhi, sesuai dengan aturan kontrak data biasa. Namun, menserialisasikan jenis IXmlSerializable sebagai ganti Object mengakibatkan hilangnya informasi jenis karena hasilnya adalah string JSON.

Polimorfisme dan Jenis Antarmuka Tertentu

Dilarang untuk membuat serialisasi jenis koleksi atau jenis yang mengimplementasikan IXmlSerializable di mana jenis non-koleksi bukan IXmlSerializable (kecuali untuk Object) yang diharapkan. Misalnya, antarmuka kustom yang disebut IMyInterface dan MyType jenis yang mengimplementasikan kedua IEnumerable<T> dari int jenis dan IMyInterface. Dilarang untuk mengembalikan MyType dari operasi yang jenis pengembaliannya adalah IMyInterface. Hal ini karena MyType harus diserialisasikan sebagai array JSON dan memerlukan petunjuk jenis, dan seperti yang dinyatakan sebelum Anda tidak dapat menyertakan petunjuk jenis dengan array, hanya dengan jenis kompleks.

Jenis dan Konfigurasi yang Diketahui

Semua mekanisme Jenis yang Diketahui yang digunakan juga oleh DataContractSerializer didukung dengan cara yang sama oleh DataContractJsonSerializer. Kedua serializer membaca elemen konfigurasi yang sama, <dataContractSerializer> dalam <system.runtime.serialization>, untuk menemukan jenis yang diketahui ditambahkan melalui file konfigurasi.

Koleksi Ditetapkan ke Objek

Koleksi yang ditetapkan ke Objek diserialisasikan seolah-olah koleksi tersebut adalah koleksi yang mengimplementasikan IEnumerable<T>: array JSON dengan setiap entri yang memiliki petunjuk jenis jika merupakan jenis kompleks. Misalnya, List<T> dari Shape jenis yang ditetapkan agar Object terlihat seperti berikut ini.

[{"__type":"Shape:#MyApp.Shapes","x":50,"y":70},
{"__type":"Shape:#MyApp.Shapes","x":58,"y":73},
{"__type":"Shape:#MyApp.Shapes","x":41,"y":32}]

Ketika dideserialisasikan kembali ke Object:

  • Shape harus berada di daftar Jenis yang Diketahui. Memiliki List<T> dari Shape jenis dalam jenis yang diketahui tidak berpengaruh. Perhatikan bahwa Anda tidak perlu menambahkan Shape ke jenis yang diketahui pada serialisasi dalam kasus ini - perilaku ini dilakukan secara otomatis.

  • Koleksi dideserialisasi sebagai Array dari Object jenis yang berisi instans Shape.

Koleksi Turunan yang Ditetapkan ke Koleksi Dasar

Ketika koleksi turunan ditetapkan ke koleksi dasar, koleksi biasanya diserialisasikan seolah-olah koleksi tersebut merupakan koleksi jenis dasar. Namun, jika tipe item dari koleksi turunan tidak dapat ditetapkan ke tipe item koleksi dasar, pengecualian akan ditampilkan.

Petunjuk Jenis dan Kamus

Ketika kamus ditetapkan ke Object, setiap entri Kunci dan Nilai dalam kamus diperlakukan seolah-olah ditetapkan ke Object dan mendapatkan petunjuk jenis.

Saat membuat serialisasi jenis kamus, objek JSON yang berisi anggota "Kunci" dan "Nilai" tidak terpengaruh oleh pengaturan alwaysEmitTypeInformation dan hanya berisi petunjuk jenis ketika aturan koleksi sebelumnya memerlukannya.

Nama Kunci JSON yang valid

XML Serializer mengodekan nama kunci yang bukan nama XML yang valid. Misalnya, anggota data dengan nama "123" akan memiliki nama yang dikodekan seperti "_x0031__x0032__x0033_" karena "123" adalah nama elemen XML yang tidak valid (dimulai dengan digit). Situasi serupa mungkin muncul dengan beberapa tataan karakter internasional yang tidak valid dalam nama XML. Untuk penjelasan tentang efek XML ini pada pemrosesan JSON, lihat Pemetaan Antara JSON dan XML.

Lihat juga