反序化暧昧的json

时间:2011-02-16 17:41:25

标签: c# xml json serialization

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" }
                          };

XmlElement属性控制xml序列化,因此导致:

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

如果我要添加类似的属性来反序列化为json(使用Newtonsoft Json.Net库):

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

但是,与xml不同,它不包含类型的详细信息,因此我不清楚它将正确识别要反序列化的类。有没有使用现有的json结构正确反序列化,或者我是否必须修改json结构(以及如何做到最好)。

我想过重写序列化,以便产生以下格式:

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

有更好的方法吗?

1 个答案:

答案 0 :(得分:2)

您可以省略嵌套的"object"=,只使用不是有效属性名称的字符串作为类标识符:

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

JSON.net内置了TypeNameHandling功能,生成的json如下所示:

{"$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}
}

请注意,如果您使用的是TypeNameHandling,则json可以构造任意类型。所以你可能不想从不受信任的来源反序列化json。