2011-05-10 85 views
2

鑑於以下類結構(其中包括派生對象字典),如何使用NewtonSoft的Json庫序列化和反序列化?當我反序列化時,我收到一個異常。看起來它有重新編制字典的問題。使用NewtonSoft的Json庫反序列化導出類型的字典

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到列表或字典,按預期工作代碼

[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通話。

我在做什麼錯?

回答

0

我有完全相同的問題...看起來像有一件有趣的事情序列化/反序列化與其中的對象的併發字典。

+0

實際上,問題看起來像它實際上是我自己的,與嵌套的序列化對象恢復的順序有關。特別是,在設置ConcurrentDictionary時,我用於我的鎖的對象在反序列化的ConcurrentDictionary設置之前沒有實例化,因此鎖正在生成空引用execption。 – 2011-10-16 14:28:05

相關問題