I serialize a dictionary to json by Newtonsoft.json and bellow code :
var serializeSettings = new JsonSerializerSettings
{
TypeNameHandli
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:
{ "$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" }
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.
Relatedly, when using TypeNameHandling
, do take note of this caution from the Newtonsoft docs:
TypeNameHandling should be used with caution when your application deserializes JSON from an external source. Incoming types should be validated with a custom SerializationBinder when deserializing with a value other than None.
For a discussion of why this may be necessary, see TypeNameHandling caution in Newtonsoft Json.