使用Json.net反序列化混合类型的列表

时间:2014-07-10 21:44:26

标签: c# serialization json.net

我正在使用Json.Net并尝试序列化和反序列化包含多种类型对象的List。我很难找到一种方法来结束包含我派生类型的对象的List,相反,我最终得到了一个基类型列表。

我的代码示例清楚地说明了发生了什么:

public class Vehicle{
    public int wheels = 4;
}
public class Truck : Vehicle {
    public int airhorns = 1;
}

static void Main (string[] args) {

    List<Vehicle> vehicles = new List<Vehicle> ();
    vehicles.Add (new Vehicle ());
    vehicles.Add (new Truck ());
    foreach (Vehicle v in vehicles) {
        Console.WriteLine ("Before deserializing, we have a: " + v.GetType ());
    }

    string s = JsonConvert.SerializeObject (vehicles);
    List<Vehicle> deserialized = JsonConvert.DeserializeObject<List<Vehicle>> (s);
    foreach (Vehicle v in deserialized) {
        Console.WriteLine ("After deserializing, we have a: " + v.GetType ());
    }
}

运行它的结果是:

Before deserializing, we have a: Vehicle
Before deserializing, we have a: Truck
After deserializing, we have a: Vehicle
After deserializing, we have a: Vehicle

我希望在我的反序列表中最终得到一辆卡车。需要注意的一点是字符串“s”中的json确实包含了airhorns变量。所以数据存在。

我已经浏览了JSON文档,并没有发现任何与我正在寻找的完全相同的内容。我查看了黑客CustomCreationConverters(http://james.newtonking.com/json/help/index.html?topic=html/CustomCreationConverter.htm),它们似乎可能用于实例化正确的派生类,但该方法不提供任何json数据,因此我无法确定类型。 / p>

我愿意添加另一个可能明确定义“Class:Vehicle”或“Class:Truck”的字段,但我还不确定如何使用它。也许在创建了正确的类之后,我可以在新对象上使用JsonConvert.PopulateObject ...但是我需要处理json片段。

有什么想法吗?谢谢!

1 个答案:

答案 0 :(得分:1)

只需设置TypeNameHandling并在序列化和反序列化中使用此设置。

var settings = new JsonSerializerSettings() { 
                  TypeNameHandling = Newtonsoft.Json.TypeNameHandling.All
               };

string s = JsonConvert.SerializeObject(vehicles, settings);
List<Vehicle> deserialized = JsonConvert.DeserializeObject<List<Vehicle>>(s,settings);

foreach (Vehicle v in deserialized)
{
    Console.WriteLine("After deserializing, we have a: " + v.GetType());
}

输出:

Before deserializing, we have a: SO3.Form1+Vehicle
Before deserializing, we have a: SO3.Form1+Truck
After deserializing, we have a: SO3.Form1+Vehicle
After deserializing, we have a: SO3.Form1+Truck