问题
如果你需要支持子类反序列化,那么需要用到Newtonsoft.json,并设置
JsonSerializerSettings settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
}
此时,所生成的 json 字符串在 .net framework(或mono) 与 .net core 之间不能通用。反序列化为对象时报错:Could not load 'System.Private.CoreLib' 或 Could not load mscorlib''。
分析
Blazor WASM 底层用的是 mono,与.net framework 一样依赖 mscorlib.dll,而.net core 依赖System.Private.CoreLib.dll,来提供系统类型,以 string 为例得到的 json字符串分别如下:
mono/.net framework: System.String, System.Private.CoreLib
.net core: System.String, mscorlib
解决办法
参考这篇文章,先定一个SerializationBinder,替换 System.Private.CoreLib 为 miscorlib
internal sealed class DotNetCompatibleSerializationBinder : DefaultSerializationBinder
{
private const string CoreLibAssembly = "System.Private.CoreLib";
private const string MscorlibAssembly = "mscorlib";
public override Type BindToType(string assemblyName, string typeName)
{
if (assemblyName == CoreLibAssembly)
{
assemblyName = MscorlibAssembly;
typeName = typeName.Replace(CoreLibAssembly, MscorlibAssembly);
}
return base.BindToType(assemblyName, typeName);
}
}
再设定JsonSerializerSettings
var settings = new JsonSerializerSettings()
{
SerializationBinder = new DotNetCompatibleSerializationBinder(),
TypeNameHandling = TypeNameHandling.All
};
结论
使用 Newtonsoft.json 序列化父子类型时,需要加上TypeNameHandling.All,加上后保存的json字符串里就包含了详细的类型信息,其中的系统类型信息 .net framework 和 mono(Blazor WASM)用的是mscorlib,.net core用的是 System.Private.CoreLib,要混用二者的序列化-反序列化,需要按上述代码的方法进行库名替换。