使用NewtonSoft的Json库对具有派生类型的字典进行反序列化 [英] Deserializing dictionary with derived types using NewtonSoft's Json library

查看:77
本文介绍了使用NewtonSoft的Json库对具有派生类型的字典进行反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于以下类结构(其中包括派生对象的字典),如何使用NewtonSoft的Json库进行序列化和反序列化?反序列化时,我得到一个例外.似乎在重构字典时遇到问题.

Given the following class structure, which includes a dictionary of derived objects, how can I serialize and deserialize using NewtonSoft’s Json library? When I deserialize, I am getting an exception. It looks like it is having issues reconstituting the dictionary.

[JsonObject(MemberSerialization.OptIn)]
public class GameObject
{
    [JsonProperty]
    public string Id { get; set; }

    [JsonProperty]
    public string Name { get; set; }

    [JsonProperty]
    public ConcurrentDictionary<string, Component> Components;

    public GameObject()
    {
        Components = new ConcurrentDictionary<string, Component>();
    }

}

[JsonObject(MemberSerialization.OptIn)]
public class Component
{
    [JsonIgnore] // Ignore circular reference
    public GameObject GameObject { get; set; }

    public Component()
    {
    }
}

[JsonObject(MemberSerialization.OptIn)]
public class TestComponent : Component
{
    [JsonProperty]
    public int MyProperty { get; set; }

    public TestComponent()
    {
    }
}




var originalJson = JsonConvert.SerializeObject(srcObject, Formatting.None, 
    new JsonSerializerSettings
                {
                    TypeNameHandling = TypeNameHandling.All,
                    TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
                });

var newObject = JsonConvert.DeserializeObject<GameObject>(originalJson, 
    new JsonSerializerSettings()
                {
                    TypeNameHandling = TypeNameHandling.All,
                    TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple
                });

DeserializeObject调用异常:

Exception on the DeserializeObject call:

System.Reflection.TargetInvocationException was unhandled by user code
  Message=Exception has been thrown by the target of an invocation.
  Source=mscorlib
  StackTrace:
       at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
       at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
       at Newtonsoft.Json.Serialization.JsonContract.InvokeOnDeserialized(Object o, StreamingContext context) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonContract.cs:line 135
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateDictionary(IWrappedDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, String id) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 638
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateDictionary(JsonReader reader, JsonDictionaryContract contract, String id) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 593
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 387
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 223
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueProperty(JsonReader reader, JsonProperty property, Object target, Boolean gottenCurrentValue, Object currentValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 198
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectFromNonDefaultConstructor(JsonReader reader, JsonObjectContract contract, String id) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 876
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, String id) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 846
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 396
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 223
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 208
       at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\Serialization\JsonSerializerInternalReader.cs:line 120
       at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\JsonSerializer.cs:line 421
       at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\JsonSerializer.cs:line 413
       at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\JsonConvert.cs:line 721
       at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings) in d:\Development\Releases\Json\Working\Src\Newtonsoft.Json\JsonConvert.cs:line 683
       at MF.Tests.GameServer.ComponentSerializationTests.TestSerializationOfObjectWithComponent() in C: \ComponentSerializationTests.cs:line 119
  InnerException: System.NullReferenceException
       Message=Object reference not set to an instance of an object.
       Source=mscorlib
       StackTrace:
            at System.Collections.Concurrent.ConcurrentDictionary`2.InitializeFromCollection(IEnumerable`1 collection)
            at System.Collections.Concurrent.ConcurrentDictionary`2.OnDeserialized(StreamingContext context)
       InnerException:

更新:

如果将ConcurrentDictionary更改为List或Dictionary,则代码将按预期工作.

If change the ConcurrentDictionary to a List or a Dictionary, the code works as expected.

我在做什么错了?

推荐答案

我遇到了完全相同的问题...看起来对序列化/反序列化带有对象的并发字典有一些有趣的事情.

I'm having exactly the same problem... Looks like there's something interesting about serialising/deserialising a concurrent dictionary with objects in it.

这篇关于使用NewtonSoft的Json库对具有派生类型的字典进行反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆