代码:
cs
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\test.json";
List<TestBase> list = new List<TestBase>();
list.Add(new Test1() { index1 = 1, Name = "a1" });
list.Add(new Test2() { index2 = 2, Name = "a2" });
list.Add(new Test3() { index3 = 3, Name = "a3" });
string json = JsonConvert.SerializeObject(list);
File.WriteAllText(path, json);
string readJson = File.ReadAllText(path);
var list2 = JsonConvert.DeserializeObject<List<TestBase>>(json);
Console.WriteLine("现在每个 Test 类的 Index 已经丢失");
Console.ReadKey();
}
}
public class TestBase
{
public string Name { get; set; }
}
public class Test1 : TestBase
{
public int index1 { get; set; }
}
public class Test2 : TestBase
{
public int index2 { get; set; }
}
public class Test3 : TestBase
{
public int index3 { get; set; }
}
在上面的代码中,将 Json 反序列化后,对于的 Index 值都会丢失,因为这种写法,父类的数据在反序列化时,没有赋值导致的
解决方式:
在序列化和反序列化时,加上下面的代码
序列化:
cs
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
};
string json = JsonConvert.SerializeObject(list, settings);
反序列化:
cs
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
};
var list2 = JsonConvert.DeserializeObject<List<TestBase>>(readJson, settings);
案例1:
cs
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
internal class Program
{
static void Main(string[] args)
{
string path = $"{Environment.CurrentDirectory}\\test.json";
// 初始化列表
List<TestBase> list = new List<TestBase>
{
new Test1() { index1 = 1, Name = "a1" },
new Test2() { index2 = 2, Name = "a2" },
new Test3() { index3 = 3, Name = "a3" }
};
// 序列化时包含类型信息
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto // 自动添加 $type 字段
};
string json = JsonConvert.SerializeObject(list, settings);
File.WriteAllText(path, json);
// 读取 JSON 并反序列化
string readJson = File.ReadAllText(path);
var list2 = JsonConvert.DeserializeObject<List<TestBase>>(readJson, settings);
// 验证反序列化后的数据
foreach (var item in list2)
{
if (item is Test1 test1)
Console.WriteLine($"Test1: {test1.Name}, index1 = {test1.index1}");
else if (item is Test2 test2)
Console.WriteLine($"Test2: {test2.Name}, index2 = {test2.index2}");
else if (item is Test3 test3)
Console.WriteLine($"Test3: {test3.Name}, index3 = {test3.index3}");
}
Console.ReadKey();
}
}
public class TestBase
{
public string Name { get; set; }
}
public class Test1 : TestBase
{
public int index1 { get; set; }
}
public class Test2 : TestBase
{
public int index2 { get; set; }
}
public class Test3 : TestBase
{
public int index3 { get; set; }
}
案例2:
cs
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
namespace 反序列化
{
internal class Program
{
static void Main(string[] args)
{
Data data = new Data();
Test1 test1 = new Test1();
test1.Name = "test1";
test1.Text = "a";
Test2 test2 = new Test2();
test2.Name = "test2";
test2.Text = "b";
test2.Value = 1;
string key = "key";
if (!data.myDic.TryGetValue(key, out var list))
{
list = new List<TestBase>();
data.myDic[key] = list;
}
list.Add(test1);
list.Add(test2);
string path = $"{Environment.CurrentDirectory}\\test.json";
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
};
string json = JsonConvert.SerializeObject(list, settings);
File.WriteAllText(path, json);
string readJson = File.ReadAllText(path);
var list2 = JsonConvert.DeserializeObject<List<TestBase>>(readJson, settings);
if(list.Count == 2)
{
if (list[0] is Test1 _test1)
{
Console.WriteLine("Test1.Name={0}, Test1.Text={1}", _test1.Name, _test1.Text);
}
if (list[1] is Test2 _test2)
{
Console.WriteLine("Test2.Name={0}, Test2.Text={1}, Test2.Value={2}", _test2.Name, _test2.Text, _test2.Value);
}
}
Console.ReadKey();
}
}
}
public class TestBase
{
public string Name { get; set; }
}
public class Test1 : TestBase
{
public string Text { get; set; }
}
public class Test2 : TestBase
{
public int Value { get; set; }
public string Text { get; set; }
}
public class Data
{
public Dictionary<string,List<TestBase>> myDic = new Dictionary<string,List<TestBase>>();
}
运行:
end