C# 将带有嵌套派生对象的C数据对象反序列化到JSON或从JSON反序列化

C# 将带有嵌套派生对象的C数据对象反序列化到JSON或从JSON反序列化,c#,json,C#,Json,是否有C库可以在一次调用中序列化.NET/C强类型对象的树状结构 编辑:我希望能够将JSON反序列化为object类型的变量或其他一些根类,但object更可取,然后通过调用此变量的GetType找出我刚刚反序列化的内容。所以,除了bool/int/float/string和每个列表之外,每个类的每个实例的类型都应该作为序列化JSON的一部分存储并自动检索 例如,如果我有这些C类: public class House { public int Number; public Li

是否有C库可以在一次调用中序列化.NET/C强类型对象的树状结构

编辑:我希望能够将JSON反序列化为object类型的变量或其他一些根类,但object更可取,然后通过调用此变量的GetType找出我刚刚反序列化的内容。所以,除了bool/int/float/string和每个列表之外,每个类的每个实例的类型都应该作为序列化JSON的一部分存储并自动检索

例如,如果我有这些C类:

public class House
{
    public int Number;
    public List<Room> Rooms;
}

public class Room
{
    public string Name;
    public int Floor;
}

public class Bathroom : Room
{
    public bool IsWet;
}
例如,要在我的jsonHouse变量EDIT中获得这个结果:请注意,它将每个类的类型存储为JSON的一部分。还要注意存储在列表中的派生类实例:

最后,我们称之为:

string jsonHouse = JSON.Serialize(myHouse);
House copyOfMyHouse = JSON.Deserialize(jsonHouse);
object copyOfMyHouse = JSON.Desrialize(jsonHouse);
编辑:上面这个电话似乎有误导性。与上述调用不同,我希望反序列化如下:

string jsonHouse = JSON.Serialize(myHouse);
House copyOfMyHouse = JSON.Deserialize(jsonHouse);
object copyOfMyHouse = JSON.Desrialize(jsonHouse);
在我的copyOfMyHouse变量中获取类House的实例,类型为object,而不指定为JSON。反序列化我希望从中得到什么类型-我可能事先不知道它

要获得myHouse变量中的精确副本,请使用List泛型类的一个实例,该实例包含对Room类的两个实例的精确副本的引用

有没有用C编写的JSON序列化程序可以做到这一点

最好是自由/开放源码软件/牙线,可以合法用于商业项目

JSON字符串的格式可能不同于我上面作为示例使用的格式,例如,您建议的解决方案可能将列表存储为JSON对象而不是数组,其他文本格式(如BSON或XML)是可以接受的 任何嵌套级别的单次调用都是必需的,否则任何JSON序列化程序都适合。 此外,还需要能够将字典序列化为JSON对象


如果我对查找内容的描述不清楚,请提出澄清问题。

基本上,您希望序列化/反序列化包含派生类型的对象。解决方案是使用。它非常简单,易于使用。以下是您的数据示例:

House myHouse = new House();
myHouse.Number = 13;

myHouse.Rooms = new List<Room>();

Room room1 = new Room();
room1.Name = "some room";
room1.Floor = 0;
myHouse.Rooms.Add(room1);

Room room2 = new Room();
room2.Name = "other room";
room2.Floor = 3;
myHouse.Rooms.Add(room2);

Bathroom bathroom = new Bathroom();
bathroom.Name = "Bathroom";
bathroom.Floor = 2;
bathroom.IsWet = true;
myHouse.Rooms.Add(bathroom);

JsonSerializerSettings settings = new JsonSerializerSettings();
settings.TypeNameHandling = TypeNameHandling.Auto;

string json = JsonConvert.SerializeObject(myHouse, settings);
Console.WriteLine("Serialize finished!");

House house = JsonConvert.DeserializeObject<House>(json, settings);
Console.WriteLine($"House number: {house.Number}; Total rooms: {house.Rooms.Count}");

foreach (Room room in house.Rooms)
{
    if (room is Bathroom)
    {
        var temp = room as Bathroom;
        Console.WriteLine($"Room name: {temp.Name}, wet: {temp.IsWet}");
    }
    else
    {
        Console.WriteLine($"Room name: {room.Name}");
    }
}
Console.WriteLine("Deserialize finished!");

Console.ReadLine();

在对字符串进行反序列化后,您将返回该对象。

Newtonsoft.JSON有时被称为JSON.NET,它很好,可以作为NuGet包使用。然后你可以写一些类似的东西:

var value = new { ID = 1, Name="test"};
string serialized = JsonConvert.SerializeObject(value);
反序列化最简单的选项,但有很多好方法:

result = JsonConvert.DeserializeObject(jsonResponse);

虽然其他答案已经提供了很好的解决方案,但这里有一个使用该类的答案


对我来说似乎过于复杂了,尽管通过将此代码塞入自定义静态方法Abbas,它可以适应单次调用的使用,DataContractJsonSerializer是否会处理像List这样的嵌套集合?是的,它也会处理集合。它会将序列化数据对象的类型存储为结果JSON的一部分吗?Abbas,例如:房间:[{class:Room,Name:some房间楼层:0,},-在这段JSON中有一个字段类,因此,如果序列化列表中的元素是从Room派生的某种类型,而不是Room本身,它将被反序列化为同一派生类的一个实例,而不是基类Room,它将与非匿名类型一起工作吗?如果是,那么它将在反序列化之后保留类型吗循环?是的,它会。显然,当你反序列化时,你需要知道你期望的类型。你也可以使用泛型,例如,这样你就可以编写一次序列化例程,让许多不同的方法调用它来序列化不同的类型。请检查我最初问题开头的编辑,我想做的部分是能够找到我刚才反序列化的内容。@Tonklin您可以使用泛型。例如,public R callwebservices字符串uri,U值{R result;..string data=jsoninvert.SerializeObjectvalue;..[Call webservice]…result=jsoninvert.DeserializeObjectresponse;return result;}。这样做意味着调用Web服务的代码不需要明确知道它所处理的数据类型。只有调用它的代码需要知道。因此,您可以使用不同的数据类型从多个不同的位置调用相同的Web服务方法。这有帮助吗?您所描述的在某些情况下确实很有用在这里,我寻找的是从JSON表示中了解数据对象类型的能力,而不是忽略它们的能力……它是否可以使用List而不是string[]?当然会:看一看。它需要明确指定要反序列化的集合类型-它将如何处理嵌套列表和/或类?就像House将列表作为其FieldsHanks之一的列表!它可以将每个类的类型存储为JSON的一部分吗?例如,它将如何处理从正在使用ad的教室派生的一些类ded to Rooms List查看我对初始问题的编辑?哦,对不起,我误读了你的问题。请检查我编辑的答案。注意JsonSerializerSettings。
var jsonString = "";
var jsonSerializer = new DataContractJsonSerializer(typeof(House));

using (var memoryStream = new MemoryStream())
using (var streamReader = new StreamReader(memoryStream))
{
    jsonSerializer.WriteObject(memoryStream, myHouse);
    memoryStream.Position = 0;
    jsonString = streamReader.ReadToEnd();
}

Console.Write("JSON form of Person object: ");
Console.WriteLine(jsonString);