C# Json.NET无法序列化集合的字典
我正在尝试序列化(稍后反序列化)一个C# Json.NET无法序列化集合的字典,c#,serialization,dictionary,set,json.net,C#,Serialization,Dictionary,Set,Json.net,我正在尝试序列化(稍后反序列化)一个字典。不幸的是,Json.NET(通过NuGet的v6.0.3)未能做到这一点。我所做的是 var value = new Dictionary<string, ISet<string>> { {"foo", new HashSet<string>{"bar"}} }; var settings = new JsonSerializerSettings { TypeNa
字典
。不幸的是,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);
现在我想用
JsonConvert.DeserializeObject<IDictionary<string, ISet<string>>>(json, settings);
一切正常。因此,typenameholling
设置(更改/省略格式不会更改任何内容)实际上破坏了反序列化
我发现,如果不设置typenameholling
设置,序列化的$type
属性就会被忽略。即,在反序列化时,类型信息仅从解析它们的目标类型获取。这很有效
设置TypeNameHandling
时,类型解析是通过Json.NET程序集中的反射进行的,该程序集不依赖于系统
程序集,因此无法解析ISet
接口。我可以通过注册AppDomain.CurrentDomain.AssemblyResolve来解决这个问题,然后像这样解析程序集
if (args.Name == "System")
{
return typeof (ISet<>).Assembly;
}
if(args.Name==“系统”)
{
返回类型(ISet)。组件;
}
但这对我来说似乎非常脆弱,因为它只解决了这个特定组件的问题,我必须为我需要的每个组件添加另一个案例
有没有人有解决这个问题的经验?非常感谢您的帮助 在以下线程中解决了类似的问题:
问题似乎是Json无法加载具有部分名称的程序集。通过使用
TypeNameAssemblyStyle=FormatterAssemblyStyle.Full
可以解决此问题。以下线程解决了类似问题:
问题似乎是Json无法加载具有部分名称的程序集。如果您在DefaultSerializationBinder.GetTypeNameFromTypeNameKey的第83行中检查NewtonSoft.Json的源代码,则可以通过使用
TypeNameAssemblyFormat=FormatterAssemblyStyle.Full
来克服此问题。。它尝试获取类型
System.Collections.Generic.Dictionary2[[System.String,mscorlib],[System.Collections.Generic.ISet
1[[System.String,mscorlib]],System]]
从组装
mscorlib.dll
Type type = assembly.GetType(typeName);
返回null。这是FormatterAssemblyStyle.Simple的一个例子
如果使用FormatterAssemblyStyle.Full,则相同类型将为:
System.Collections.Generic.Dictionary2[[System.String,mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089],[System.Collections.Generic.ISet
1[[System.String,mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089]],系统,版本=4.0.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089]]
然后:
Type type = assembly.GetType(typeName);
将起作用,因此反序列化也起作用
但是,我无法解释为什么会出现这种情况。如果您检查DefaultSerializationBinder.GetTypeNameFromTypeNameKey第83行中NewtonSoft.Json的源代码。。它尝试获取类型 System.Collections.Generic.Dictionary
2[[System.String,mscorlib],[System.Collections.Generic.ISet
1[[System.String,mscorlib]],System]]
从组装
mscorlib.dll
Type type = assembly.GetType(typeName);
返回null。这是FormatterAssemblyStyle.Simple的一个例子
如果使用FormatterAssemblyStyle.Full,则相同类型将为:
System.Collections.Generic.Dictionary2[[System.String,mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089],[System.Collections.Generic.ISet
1[[System.String,mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089]],系统,版本=4.0.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089]]
然后:
Type type = assembly.GetType(typeName);
将起作用,因此反序列化也起作用
我说不出为什么会这样。ISet驻留在System.dll中。您的示例在json.NET和.NET 4.5的同一版本中运行良好。有趣的是,我使用的是.NET 4.0,但我认为这不是问题所在。。。我会深入研究的。我在将设置传递到反序列化中时找到了错误的原因。我相应地更新了我的问题。虽然眼前的问题已经解决了,但我真的很感兴趣,为什么传递设置会导致此错误!ISet驻留在System.dll中。您的示例在json.NET和.NET 4.5的同一版本中运行良好。有趣的是,我使用的是.NET 4.0,但我认为这不是问题所在。。。我会深入研究的。我在将设置传递到反序列化中时找到了错误的原因。我相应地更新了我的问题。虽然眼前的问题已经解决了,但我真的很感兴趣,为什么传递设置会导致此错误!很抱歉我之前的评论,这确实解决了问题。虽然我不太明白为什么。。。谢谢很抱歉我之前的评论,这确实解决了问题。虽然我不太明白为什么。。。谢谢谢谢你的解释,帮了我很多忙+1美元。不过,我接受爱丁的回答,因为他早些时候提出了同样的解决方案。不过,非常感谢!谢谢你的解释,帮了我很多忙+1美元。不过,我接受爱丁的回答,因为他早些时候提出了同样的解决方案。不过,非常感谢!