C# 是否可以序列化System.Text.Json中列表成员的派生属性?

C# 是否可以序列化System.Text.Json中列表成员的派生属性?,c#,serialization,.net-core,.net-core-3.0,system.text.json,C#,Serialization,.net Core,.net Core 3.0,System.text.json,根据报告: 要序列化派生类型的属性,请使用以下方法之一: (……) 将要序列化的对象声明为对象 不幸的是,正如我刚刚发现的,这不允许序列化列表成员的派生属性。考虑下面的DTO类: 公共抽象类游戏更新 { 公共抽象字符串类型{get;} } 公共类控制台消息:游戏更新 { 公共重写字符串类型=>“ConsoleMessage”; 公共字符串MessageContent{get;set;} } 公共类HitpointsUpdate:GameUpdate { 公共重写字符串类型=>“Hitpoin

根据报告:

要序列化派生类型的属性,请使用以下方法之一:

  • (……)
  • 将要序列化的对象声明为
    对象
不幸的是,正如我刚刚发现的,这不允许序列化列表成员的派生属性。考虑下面的DTO类:

公共抽象类游戏更新
{
公共抽象字符串类型{get;}
}
公共类控制台消息:游戏更新
{
公共重写字符串类型=>“ConsoleMessage”;
公共字符串MessageContent{get;set;}
}
公共类HitpointsUpdate:GameUpdate
{
公共重写字符串类型=>“HitpointsUpdate”;
公共长ID{get;set;}
公共长NewHP{get;set;}
}
它们应该用作
列表
。不幸的是,将要序列化的列表声明为
对象
仍然无法序列化重要属性:

var gameUpdates=新列表
{
新控制台消息{MessageContent=“Chimzee失去10点生命!”,
新HitpointsUpdate{MonsterID=5,NewHP=90}
};
var json=System.Text.json.JsonSerializer.Serialize(游戏更新);
Console.WriteLine(json);
这将生成以下JSON:

[{“Type”:“ConsoleMessage”},{“Type”:“HitpointsUpdate”}]
为了进行比较,使用
Newtonsoft.Json.JsonConvert.SerializeObject(gameUpdates)
会产生以下结果:

[{“Type”:“ConsoleMessage”,“MessageContent”:“Chimzee失去10点生命!”},{“Type”:“HitpointsUpdate”,“MonsterID”:5,“NewHP”:90}]
使用
System.Text.Json
是否可以获得类似的结果

为什么我要问这个:我一直在尝试开发一个基于浏览器的游戏作为一个爱好项目,这正是我实现服务器与浏览器通信的方式。随着Asp.NETCore3的问世。阅读文档后,我删除了与Newtonsoft相关的代码,并开始使用System.Text.Json,结果发现游戏不再运行。

这可以:

var gameUpdates = new List<object>
{
    new ConsoleMessage { MessageContent = "Chimzee lost 10 HP!"},
    new HitpointsUpdate { MonsterID = 5, NewHP = 90 }
};

var json = JsonSerializer.Serialize(gameUpdates);
Console.WriteLine(json);
var gameUpdates=新列表
{
新控制台消息{MessageContent=“Chimzee失去10点生命!”,
新HitpointsUpdate{MonsterID=5,NewHP=90}
};
var json=JsonSerializer.Serialize(游戏更新);
Console.WriteLine(json);

旁注:您的方法可能很危险,您必须保留一个允许类型的白名单,以便再次反序列化,否则攻击者可能会注入自己类型的创建过程……在一个集合中序列化一种类型的对象要安全得多

如果攻击者注入这样的代码怎么办:

“类型”:“系统.绘图.位图”,“宽度”:“100000”,“高度”:“100000”


在C#方面,我验证了预期的任何类型都可以从JSON提供的类型分配-因此在本例中,我相信
System.Drawing.Bitmap
将无法通过此验证,因为
GameUpdate
不能从
System.Drawing.Bitmap
分配。在JS方面,这并不重要幸运的是,有时动态类型似乎真的很方便。也许像你建议的那样使用单一类型会更好,但我不知道怎么做,因为不同的情况需要使用不同的信息集进行不同的更新。另一个问题是,如果
ConsoleMessageUpdate
包含遵循相同模式的属性,即存在一个抽象类
ConsoleMessagePart
和派生类
ConsoleMessagePart
consolemessageextpart
,…,和
ConsoleMessageUpdate
包含属性
List Parts{get;set;}
(这种情况下…)-我必须将此列表的类型切换到
List
。。。呃,这已经有误导性了,我想我正在切换回JSON.NET。当序列化程序迫使我更改代码并使其变得更糟(使用对象)时,该库就失败了。