首页 > 解决方案 > 当特定的类被强制转换为其他东西时,JsonSerializer 的行为不像预期的那样

问题描述

我试图从 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 一样工作?我可以通过的选项并不表明这是可配置的。我忽略了什么吗?

标签: c#jsonjson.net.net-core-3.0system.text.json

解决方案


这是因为序列化程序使用泛型参数的类型,而不是传递值的类型:

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);

推荐阅读