C# Newtonsoft.Json,填充字典失败
我通过Newtonsoft.json和下面的代码将字典序列化为json:C# Newtonsoft.Json,填充字典失败,c#,json,dictionary,serialization,json.net,C#,Json,Dictionary,Serialization,Json.net,我通过Newtonsoft.json和下面的代码将字典序列化为json: var serializeSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormat = FormatterAssemblyStyle.Full, Formatting = Formatti
var serializeSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full,
Formatting = Formatting.Indented
};
var serializedObject = JsonConvert.SerializeObject(dic, serializeSettings);
此代码生成如下所示的json:
{
"$type": "System.Collections.Generic.Dictionary`2[[System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"9648af76-7986-4b34-8b2c-97b2345769ef": "Test"
}
我尝试通过以下代码将json反序列化到字典:
var newDic = new Dictionay<Guid,string>();
var deserializeSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full,
Formatting = Formatting.Indented
}
JsonConvert.PopulateObject(serializedObject, newDic, deserializeSettings);
为什么?问题在于您在序列化词典时指定了。这将导致元数据
“$type”
属性作为字典中的第一个对象发出:
当使用反序列化时,Json.NET通常会在构造相应的c#对象时使用此令牌。但您正在使用预先分配的词典。因此,在构造过程中不会使用元数据属性,而是Json.NET尝试将其添加到字典中,但失败了
解决方案是在反序列化设置中设置。这样做将导致无条件地使用或忽略“$type”
属性(视情况而定):
var deserializeSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full,
Formatting = Formatting.Indented,
MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead
};
JsonConvert.PopulateObject(serializedObject, newDic, deserializeSettings);
请注意,从中可以看出,使用此设置在内存使用和速度方面会有轻微的成本
或者,如果您在JSON中不需要无条件的元数据类型信息,您可以使用TypeNameHandling=TypeNameHandling.Auto
进行序列化,并且只发出多态类型的类型信息,而您的字典
则不需要
相关地,当使用类型名称处理
时,请注意以下注意事项:
当应用程序从外部源反序列化JSON时,应谨慎使用TypeNameHandling。当使用非None的值反序列化时,应使用自定义SerializationBinder验证传入类型
有关为什么需要这样做的讨论,请参阅。是否需要数据特殊设置和Guid?也许可以尝试一些更简单的方法,比如JsonConvert.SerializeObject(dic)
并查看这是否为您提供了所需的。@我使用泛型类来序列化和反序列化项目中的多个类型。我的项目中的其他类型需要更改此设置。请阅读上次编辑的问题使用字符串而不是Guid@Fred@ZehraSubaş在我问题的最后一次编辑中,我这样做了,但是。。
Kay: "$type"
Value : "System.Collections.Generic.Dictionary`2[[System.Guid, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
{
"$type": "System.Collections.Generic.Dictionary`2[[System.Guid, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",
"9648af76-7986-4b34-8b2c-97b2345769ef": "Test"
}
var deserializeSettings = new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
TypeNameAssemblyFormat = FormatterAssemblyStyle.Full,
Formatting = Formatting.Indented,
MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead
};
JsonConvert.PopulateObject(serializedObject, newDic, deserializeSettings);