2011-02-16 36 views
4
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序列化所以这会导致:反序列化JSON暧昧

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

有没有更好的办法?

回答

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。