使用NewtonSoft.JSON序列化接口/抽象对象

反序列化接口和抽象属性的一种方法是类,是在序列化和反序列化期间将TypeNameHandling设置为Auto。但是,当我尝试直接对接口对象进行序列化和反序列化时,它不起作用-

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;

}

}

序列化和反序列化代码-

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

我注意到,即使在设置TypeNameHandling.Auto时,类型信息也不会出现在序列化字符串中。但是,将TypeNameHandling设置为Object或All即可。

我在这里缺少基本的东西吗?

回答:

要启用具有多态对象

的根级$type信息输出,请使用以下重载:。从文档:

__TypeNameHandling.AutoJsonConvert.SerializeObject Method (Object, Type,

JsonSerializerSettings)

public static string SerializeObject(

Object value,

Type type,

JsonSerializerSettings settings

)

type

类型:System.Type要序列化的值的类型。如果值的类型不匹配,则当TypeNameHandling为“自动”以写出类型名称时,将使用此参数。指定类型是可选的。

就您而言,您可以这样做:

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

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

Console.WriteLine(stringA);

Console.WriteLine(stringB);

并得到结果:

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

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

请注意Newtonsoft文档中的这一警告:

当您的应用程序从外部源反序列化JSON时,应谨慎使用TypeNameHandling。反序列化除None以外的其他值时,应使用自定义SerializationBinder验证传入的类型。

有关为什么这样做的必要性的讨论,请参阅Newtonsoft

Json中的TypeNameHandling警告,如何配置Json.NET以创建易受攻击的Web

API,以及AlvaroMuñoz和Oleksandr

Mirosh的blackhat论文https://www.blackhat.com/docs/我们17 /周四/us-17-Munoz-Friday-

The-13th-JSON-Attacks-

wp.pdf

以上是 使用NewtonSoft.JSON序列化接口/抽象对象 的全部内容, 来源链接: utcz.com/qa/418211.html

回到顶部