Pertanyaan Deserializing ambigu json


public abstract class A {
    public string Foo{ get; set; }
}

public class B : A {
    public string Marco{ get; set; }
}

public class C : A {
    public string Las{ get; set; }
}

public class D : A {
    public string Las{ get; set; }
}

public class SerializeMe {
    [XmlElement("b", typeof(B))]
    [XmlElement("c", typeof(C))]
    [XmlElement("d", typeof(D))]
    public A[] serializeProp { get; set; }
}

SerializeMe me = new SerializeMe();
me.serializeProp = new A[]{
                           new B(){ Foo = "bar", Marco = "polo" },
                           new C(){ Foo = "bar", Las = "Vegas" },
                           new D(){ Foo = "bar", Las = "Vegas" }
                          };

The XmlElement atribut kontrol serialisasi xml jadi ini menghasilkan:

 <SerializeMe>
    <B><Foo>bar</Foo><Marco>polo</Marco></B>
    <C><Foo>bar</Foo><Las>Vegas</Las></C>
    <D><Foo>bar</Foo><Las>Vegas</Las></D>
 </SerializeMe>

Dan jika saya harus menambahkan atribut yang sama untuk deserialize ke json (menggunakan Newtonsoft Json.Net library):

{[
    {"Foo":"bar", "Marco":"polo"},
    {"Foo":"bar", "Las":"Vegas"},
    {"Foo":"bar", "Las":"Vegas"}
]}

Namun, tidak seperti xml itu tidak mengandung rincian pada jenis, sehingga tidak jelas bagi saya bahwa itu akan benar mengidentifikasi kelas yang akan deserialize ke. Apakah ada juga deserializing dengan benar menggunakan struktur json yang ada, atau apakah saya harus memodifikasi struktur json (dan bagaimana cara terbaik untuk melakukannya).

Saya berpikir untuk meng-override serialisasi sehingga menghasilkan format berikut:

{[
    {"class":"B",
     "object":{"Foo":"bar", "Marco":"polo"}},
    {"class":"C",
     "object":{"Foo":"bar", "Las":"Vegas"}},
    {"class":"D",
     "object":{"Foo":"bar", "Las":"Vegas"}}
]}

Apakah ada cara yang lebih baik?


4
2018-02-16 17:41


asal


Jawaban:


Anda bisa membiarkannya bersarang "object"= dan cukup gunakan string yang bukan nama properti yang valid sebagai pengidentifikasi kelas:

{"Foo":"bar", "Marco":"polo", "$Class"="B"}

JSON.net memiliki fitur TypeNameHandling yang dibangun di dalam, json yang dihasilkan terlihat seperti ini:

{"$type":"Tests.MessageWrapper2, Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"Headers":{"$type":"System.Collections.Hashtable, mscorlib, Version=2.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089","DeliverAt":"yesterday!"},
"Body":{"$type":"Tests.TestMessage1, Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null","Id":893239}
}

Perhatikan bahwa jika Anda menggunakan TypeNameHandling json dapat membuat tipe arbitrer. Jadi Anda mungkin tidak ingin deserialize json dari sumber yang tidak dipercaya.


2
2018-02-16 17:44