本文介绍了Newtonsoft.Json,填充字典失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! var serializeSettings = new JsonSerializerSettings 我将序列化一个字典到json by Newtonsoft.json { 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:测试} 我尝试通过此代码将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); 但是发生这种异常:我写这样的GuidConverter并使用它。但不工作 public class GuidConverter:JsonConverter { public override bool CanConvert(Type objectType) { return objectType.IsAssignableFrom(typeof(Guid)); public override object ReadJson(JsonReader reader,Type objectType,object existingValue,JsonSerializer serializer) { try { return serializer.Deserialize<&的Guid GT;(读取器); } catch { return Guid.Empty; } } public override void WriteJson(JsonWriter writer,object value,JsonSerializer serializer) { serializer.Serialize(writer,value); } } 编辑: p> 我发现我的问题。将代码更改为序列化json到Dictionary<字符串,字符串>现在生成的字典中的第一个项目是: Kay:$ 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 为什么? 解决方案 问题是指定 TypeNameHandling = TypeNameHandling.All 当序列化你的字典。这将导致元数据$ type属性作为字典中的第一个对象发布:当使用 DeserializeObject ,当构造相应的c#对象时,该令牌通常由Json.NET使用。但是您正在使用 PopulateObject 在预先分配的字典上。因此,元数据属性在构建期间不会消耗,而Json.NET会尝试将其添加到字典中,并失败。 解决方案设置 MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead 在 deserializeSettings 。这样做会导致$ 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 序列化,并且只会发布多态类型的类型信息,您的 Dictionary< Guid,string> 不是。 I serialize a dictionary to json by Newtonsoft.json and bellow code :var serializeSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormat = FormatterAssemblyStyle.Full, Formatting = Formatting.Indented }; var serializedObject = JsonConvert.SerializeObject(dic, serializeSettings);this code generate a json like this :{ "$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"}I try to deserialize json to dictionary by this code :var newDic = new Dictionay<Guid,string>();var deserializeSettings = new JsonSerializerSettings{ TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormat = FormatterAssemblyStyle.Full, Formatting = Formatting.Indented}JsonConvert.PopulateObject(serializedObject, newDic, deserializeSettings);But this exception occurs :I write GuidConverter like this and use it. but not workpublic class GuidConverter : JsonConverter{ public override bool CanConvert(Type objectType) { return objectType.IsAssignableFrom(typeof(Guid)); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { try { return serializer.Deserialize<Guid>(reader); } catch { return Guid.Empty; } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { serializer.Serialize(writer, value); }}EDIT:I found my problem. Change code to deserialize json to Dictionary< string, string > and now First item in generated dictionary is :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"Why?? 解决方案 The problem is that you have specified TypeNameHandling = TypeNameHandling.All when serializing your dictionary. This causes a metadata "$type" property to be emitted as the first object in the dictionary:When deserializing using DeserializeObject, this token is normally consumed by Json.NET when the corresponding c# object is constructed. But you are using PopulateObject on a pre-allocated dictionary. Thus the metadata property is not consumed during construction and instead Json.NET tries to add it to the dictionary, and fails.The solution is to set MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead in deserializeSettings. Doing so will cause the "$type" property to be consumed or ignored (as appropriate) unconditionally:var deserializeSettings = new JsonSerializerSettings{ TypeNameHandling = TypeNameHandling.All, TypeNameAssemblyFormat = FormatterAssemblyStyle.Full, Formatting = Formatting.Indented, MetadataPropertyHandling = MetadataPropertyHandling.ReadAhead};JsonConvert.PopulateObject(serializedObject, newDic, deserializeSettings);Please note that, from the release notes, there is a slight cost in memory usage and speed from using this setting.Alternatively, if you don't unconditionally need metadata type information in your JSON, you could serialize with TypeNameHandling = TypeNameHandling.Auto and only emit type information for polymorphic types, which your Dictionary<Guid, string> is not. 这篇关于Newtonsoft.Json,填充字典失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-07 14:32