Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用NewtonSoft.JSON序列化接口/抽象对象_C#_Json_Serialization_Json.net - Fatal编程技术网

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

C# 使用NewtonSoft.JSON序列化接口/抽象对象,c#,json,serialization,json.net,C#,Json,Serialization,Json.net,反序列化接口和抽象属性的一种方法是类,即在序列化和反序列化期间将TypeNameHandling设置为Auto。但是,当我在直接序列化和反序列化接口对象时尝试同样的方法时,它不起作用- interface ISample { string Key { get; set; } } class A : ISample { public string Key { get; set; } public A(string key) { this.Key

反序列化接口和抽象属性的一种方法是类,即在序列化和反序列化期间将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);
ISample a=新的a(“keyA”);
ISample b=新的b(“键b”);
var settings=new JsonSerializerSettings();
settings.typenameholling=typenameholling.Auto;
var stringA=JsonConvert.SerializeObject(a,设置);
var stringB=JsonConvert.SerializeObject(b,设置);
控制台写入线(stringA);
控制台写入线(stringB);
a=JsonConvert.DeserializeObject(stringA,设置);
b=JsonConvert.DeserializeObject(stringB,设置);
我注意到,即使在设置TypeNameHandling.Auto时,序列化字符串中也不存在类型信息。但是,设置TypeNameHandling对对象或所有对象都有效


这里缺少一些基本信息吗?

要在根级别为具有
TypeNameHandling.Auto
的多态对象启用
$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"}
请注意以下注意事项:

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

有关为什么这可能是必要的讨论,请参阅和Alvaro Muñoz&Oleksandr Mirosh的blackhat论文

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