System.Text.Json.JsonSerializer不会序列化派生类的属性

时间:2019-12-10 00:45:03

标签: .net-core

我无法从派生类获得System.Text.Json.JsonSerializer序列化属性。 Newtonsoft的工作没有问题。

namespace TestJson
{
    class Program
    {
        static void Main(string[] args)
        {
            var myClass = new NewClass2
            {
                Value1 = "qsd",
                ShouldBeSerialized = "why am I not serialized?"
            };

            // as expected, getting {"ShouldBeSerialized":"why am not serialized?","Value1":"qsd"}
            var textJsonSerializedFromTop = System.Text.Json.JsonSerializer.Serialize<NewClass2>(myClass);

            // expecting {"ShouldBeSerialized":"why am not serialized?","Value1":"qsd"}
            // but getting {"Value1":"qsd"}
            var textJsonSerializedFromBase = System.Text.Json.JsonSerializer.Serialize<ClassBase>(myClass);

            // as expected, getting {"ShouldBeSerialized":"why am not serialized?","Value1":"qsd"}
            var newtonSoftSerializedFromBase = Newtonsoft.Json.JsonConvert.SerializeObject(myClass);
        }
    }
    public class ClassBase
    {
        public string Value1 { get; set; }
    }
    public class NewClass2 : ClassBase
    {
        public string ShouldBeSerialized { get; set; }
    }
}

在前面的示例中,我们展示了实际的问题,解决方案很简单,但是在下面的示例中,我不知道如何通过不使用newtonsoft进行管理:

namespace TestJson
{
    class Program
    {
        static void Main(string[] args)
        {
            var toSerialize =
                new[] {
                    new ClassBase
                    {
                        Value1 = "aze"
                    },
                    new NewClass2
                    {
                        Value1="qsd",
                        ShouldBeSerialized="why am I not serialized?"
                    }
                 };
            var textJsonSerialized = System.Text.Json.JsonSerializer.Serialize(toSerialize);
            // expecting [{"Value1":"aze"},{"ShouldBeSerialized":"why am not serialized?","Value1":"qsd"}]
            // but getting [{"Value1":"aze"},{"Value1":"qsd"}]
            Console.WriteLine(textJsonSerialized);

            var newtonSoftSerialized =  Newtonsoft.Json.JsonConvert.SerializeObject(toSerialize);
            // as expected getting [{"Value1":"aze"},{"ShouldBeSerialized":"why am not serialized?","Value1":"qsd"}]

            Console.WriteLine(newtonSoftSerialized);
        }
    }
    public class ClassBase
    {
        public string Value1 { get; set; }
    }
    public class NewClass2 : ClassBase
    {
        public string ShouldBeSerialized { get; set; }
    }
}

1 个答案:

答案 0 :(得分:0)

JsonSerializer类接受类型参数(通过通用方法或作为显式参数),该参数表示要序列化为的静态数据类型。这样可以防止一类衍生数据类型的意外数据泄露错误,这些错误不知道它们正在被序列化。

问题中的代码使用JsonSerializer.Serialize(toSerialize)形式。由于没有提供System.Type值作为第二个参数,因此将调用泛型方法JsonSerializer.Serialize<TValue>(TValue value),并且通过泛型推断,将toSerialize值具有的任何类型作为TValue提供。因此,它说“将toSerialize完全序列化为ClassBase的数组”,而对于ClassBase数组,则是“将元素完全序列化为ClassBase的序列”。

如果您想要多态的序列化,则可以通过将序列化为动态类型toSerialize来实现(在这种情况下,这是没有用的,因为动态类型和静态类型类型相同),或将其序列化为类型System.Object,表示“从头到尾都是多态的”。请注意,JsonSerializer不支持多态反序列化(通常,多态反序列化是安全漏洞的绝妙开放领域)。

多态序列化技术:

  • JsonSerializer.Serialize<object>(toSerialize)
  • JsonSerializer.Serialize(toSerialize, typeof(object))
  • JsonSerializer.Serialize(toSerialize, toSerialize.GetType())(在这种情况下不起作用,因为您想要成员或元素的多态值,而不是根值的多态序列化。)