采用序列NewtonSoft.JSON接口/抽象对象 [英] Serializing an interface/abstract object using NewtonSoft.JSON

查看:220
本文介绍了采用序列NewtonSoft.JSON接口/抽象对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

反序列化接口和抽象属性的一种方式是一类被序列化和反序列化过程中设置TypeNameHandling为自动。然而,当我序列化和直接反序列化的接口对象时尝试同样的,这是行不通的 -

 接口ISample 
{
字符串键{获得;组; }
}

类答:ISample
{
公共字符串键{获得;组; }

公开发行A(字符串键)
{
this.Key =键;
}
}

B类:ISample
{
公共字符串键{获得;组; }

公众B(字符串键)
{
this.Key =键;
}
}



序列化和反序列化的代码 -

  ISample一个新= A(科亚); 
ISample B =新B(KEYB);

VAR设置=新JsonSerializerSettings();
settings.TypeNameHandling = TypeNameHandling.Auto;

VAR stringA = JsonConvert.SerializeObject(一,设置);
VAR stringB = JsonConvert.SerializeObject(B,设置);

Console.WriteLine(stringA);
Console.WriteLine(stringB);

A = JsonConvert.DeserializeObject< ISample>(stringA,设置);
B = JsonConvert.DeserializeObject< ISample>(stringB,设置);



我注意到,设置TypeNameHandling.Auto类型的信息,即使不存在序列化的字符串。然而,设置TypeNameHandling到对象或全部的作品。



我失去了一些基本的东西在这里?


解决方案

要允许输出 $类型信息的在根级别的一个多态对象与 TypeNameHandling.Auto ,使用以下过载: JsonConvert.SerializeObject方法(对象,类型,JsonSerializerSettings) 。从文档




 公共静态字符串SerializeObject(
对象的值,$ b $型b型,
JsonSerializerSettings设置

键入
类型:System.Type
该类型的值被序列化。当TypeNameHandling是自动写出来,如果​​该值的类型不匹配的类型名称使用此参数。 Specifing类型是可选的。




在你的情况,你会怎么做:

  VAR stringA = JsonConvert.SerializeObject(一的typeof(ISample),设置); 
VAR stringB = JsonConvert.SerializeObject(B的typeof(ISample),设置);

Console.WriteLine(stringA);
Console.WriteLine(stringB);

和得到的结果:

  {$类型:Tile.TestJsonDotNet.A,瓷砖,重点:科亚} 
{$类型:Tile.TestJsonDotNet.B,瓷砖,重点:KEYB}


One way of deserializing interface and abstract properties is a class is by setting TypeNameHandling to Auto during serialization and deserialization. However, when I try the same when serializing and deserializing an interface object directly, it does not work -

    interface ISample
    {
        string Key { get; set; }
    }

    class A : ISample
    {
        public string Key { get; set; }

        public A(string key)
        {
            this.Key = key;
        }
    }

    class B : ISample
    {
        public string Key { get; set; }

        public B(string key)
        {
            this.Key = key;
        }
    }

Serialization and deserialization code -

        ISample a = new A("keyA");
        ISample b = new B("keyB");

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

        var stringA = JsonConvert.SerializeObject(a, settings);
        var stringB = JsonConvert.SerializeObject(b, settings);

        Console.WriteLine(stringA);
        Console.WriteLine(stringB);

        a = JsonConvert.DeserializeObject<ISample>(stringA, settings);
        b = JsonConvert.DeserializeObject<ISample>(stringB, settings);

I noticed that even when setting TypeNameHandling.Auto the type information is not present in the serialized string. However, settings TypeNameHandling to Object or All works.

Am I missing something basic here?

解决方案

To enable output of $type information at the root level for a polymorphic object with TypeNameHandling.Auto, use the following overload: JsonConvert.SerializeObject Method (Object, Type, JsonSerializerSettings). From the docs:

public static string SerializeObject(
    Object value,
    Type type,
    JsonSerializerSettings settings
)

type Type: System.Type The type of the value being serialized. This parameter is used when TypeNameHandling is Auto to write out the type name if the type of the value does not match. Specifing the type is optional.

In your case, you would do:

        var stringA = JsonConvert.SerializeObject(a, typeof(ISample), settings);
        var stringB = JsonConvert.SerializeObject(b, typeof(ISample), settings);

        Console.WriteLine(stringA);
        Console.WriteLine(stringB);

And get the result:

{"$type":"Tile.TestJsonDotNet.A, Tile","Key":"keyA"}
{"$type":"Tile.TestJsonDotNet.B, Tile","Key":"keyB"}

这篇关于采用序列NewtonSoft.JSON接口/抽象对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆