我正在尝试序列化(然后反序列化)一个 Dictionary<string, ISet<string>> .不幸的是,Json.NET(通过 NuGet 的 v6.0.3)无法做到这一点。我做的是
var value = new Dictionary<string, ISet<string>>
{
{"foo", new HashSet<string>{"bar"}}
};
var settings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
};
var json = JsonConvert.SerializeObject(value, settings);
变量json然后持有字符串
{"$type":"System.Collections.Generic.Dictionary`2[[System.String, mscorlib],[System.Collections.Generic.ISet`1[[System.String, mscorlib]], System]], mscorlib","foo":["bar"]}
现在我想反序列化字符串
JsonConvert.DeserializeObject<IDictionary<string, ISet<string>>>(json, settings);
无法解析字典类型,因为它找不到 System组装ISet属于。当我改为执行以下操作时
JsonConvert.DeserializeObject<IDictionary<string, ISet<string>>>(json);
一切正常。所以看起来 TypeNameHandling设置(更改/省略格式不会改变任何内容)实际上会破坏反序列化。
我发现,如果我不设置 TypeNameHandling设置,序列化$type属性被简单地忽略了。即,在反序列化时,类型信息仅取自解析它们的目标类型。这行得通。
设置 TypeNameHandling 时,类型解析通过 Json.NET 程序集中的反射发生,它不依赖于 System程序集,因此无法解决 ISet界面。我可以通过在 AppDomain.CurrentDomain.AssemblyResolve 上注册来解决这个问题并像这样解决程序集
if (args.Name == "System")
{
return typeof (ISet<>).Assembly;
}
但这对我来说似乎非常脆弱,因为它只解决了这个特定程序集的问题,我必须为我在某处需要的每个程序集添加另一个案例。
有没有人有解决这个问题的经验?非常感谢任何帮助!
请您参考如下方法:
以下线程中解决了类似的问题:How can I deserialize with TypeNameHandling.Objects in Json.NET Silverlight?
问题似乎是 Json 无法加载具有部分名称的程序集。您可以使用 TypeNameAssemblyFormat = FormatterAssemblyStyle.Full 来解决这个问题。
