![](/img/trans.png)
[英]JsonSerializer.Deserialize expected to throw exception when deserializing different class
[英]JsonSerializer behaves not as expected when the specifc class is casted to something else
我试图从 json.net 迁移到微软的 json 并发现一些行为非常不同的东西。
让我们使用这个简化的例子:
public interface IName
{
string Name { get; set; }
}
public class Person : IName
{
public string Name { get; set; }
public int Age { get; set; }
}
public void Foo()
{
IName p = new Person {Age = 4, Name = "Waldo"};
var s1 = System.Text.Json.JsonSerializer.Serialize(p); // --> {"Name":"Waldo"}
var s2 = Newtonsoft.Json.JsonConvert.SerializeObject(p); // --> {"Name":"Waldo","Age":4}
}
Microsoft 的 Serializers 序列化来自 IName 的属性 JSON.NET 序列化来自 Person 的属性
有没有办法配置它,让它像 JSON.NET 一样工作? 我可以通过的选项并不表明这是可配置的。 我忽略了什么吗?
这是因为序列化程序使用泛型参数的类型,而不是传递值的类型:
public static string Serialize<TValue>(TValue value, JsonSerializerOptions options = null)
{
return WriteCoreString(value, typeof(TValue), options);
}
这会将typeof(IName)
传递给WriteCoreString
,并最终在该类型上执行反射。
您可以通过将类型显式传递给接受以下内容的重载来解决此问题:
var s3 = System.Text.Json.JsonSerializer.Serialize(p, p.GetType());
这将返回:
{"Name":"Waldo","Age":4}
转换为object
也可以,因为代码然后调用value.GetType()
:
var s4 = System.Text.Json.JsonSerializer.Serialize((object)p);
请参阅序列化派生类的属性
不支持多态类型层次结构的序列化。 例如,如果属性定义为接口或抽象 class,则即使运行时类型具有附加属性,也只会序列化接口或抽象 class 上定义的属性。 本节说明了此行为的例外情况。
(此处为示例)
此行为旨在帮助防止意外暴露派生的运行时创建的类型中的数据。
接着:
要序列化派生类型的属性,请使用以下方法之一:
调用允许您在运行时指定类型的 Serialize 重载:
json = JsonSerializer.Serialize(weatherForecast, weatherForecast.GetType());
将 object 声明为 object。
json = JsonSerializer.Serialize<object>(weatherForecast);
Newtonsoft.Json.JsonConvert.SerializeObject
是一种非泛型方法,因此它会在运行时分析提供的 object 并序列化 ZA8CFDE6331BD59EB2AC96F8911C4B666 的所有属性。
相比之下System.Text.Json.JsonSerializer.Serialize(p)
被解析为通用方法。 对于相同的IName
,编译器会根据变量的类型推断类型参数。 因此,该方法分析提供的类型并导出泛型类型参数的属性,而不是实现该接口的 object 的所有属性。
文档显示,serialize 方法总是需要通过泛型类型参数或作为方法的参数来指定类型。
以下代码应修复该行为:
var s1 = System.Text.Json.JsonSerializer.Serialize(p, p.GetType());
// --> {"Name":"Waldo","Age":4}
请参阅此示例。
我认为您需要将 object 的引用传递给该方法
IName p = new Person { Age = 4, Name = "Waldo" };
var s1 = System.Text.Json.JsonSerializer.Serialize<Person>((Person)p);
适用于 .NET 核心 3.0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.