2016-11-04 22 views
0

我知道過去有很多使用Newtonsoft的反序列化問題,但是我一直無法找到與我的情況完全一致的東西。 (如果我無意中問了一個重複的問題,請讓我知道,我很難相信我是第一個遇到這種情況的人)。如何知道在反序列化JSON字符串時要將JObject投射到什麼類型

我有一個對象的結構是這樣的:

public class Logger 
    { 
     public List<MethodAPI> List { get; set; } 
    } 

    private class MethodAPI 
    { 
     public string MethodName { get; set; } 
     public List<Parameter> Parameters { get; set; } 
    } 

現在對於I型遇到了麻煩,反序列化。如果我做了如下的事情:

public class Parameter 
    { 
     public IProduct data { get; set; } 
    } 

然後反序列化工作就好了。但是,我不知道什麼類型的data直到運行時纔會出現。但是,如果我做到以下幾點:

public class Parameter 
{ 
    public object data { get; set; } 
} 

顯然,當我去反序列化這個Newtonsoft沒有解決什麼類型的這實際上應該是的方式。因此,它只是使其成爲JObject

通常,我只是寫一個自定義轉換器。但是,我不確定在這種情況下如何實施ReadJson方法。

public class ParameterConverter : JsonConverter 
    { 
     public override bool CanConvert(Type objectType) 
     { 
      return objectType.Equals(typeof(Parameter)); 
     } 

     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
     { 
      // I'd rather just do serializer.Deserialize<Parameter>(reader) here but that'll cause a stack overflow exception 
      object obj = serializer.Deserialize(reader); 
      Parameter param = (obj as JObject).ToObject<Parameter>(); 

      // This works great if I know that I'm converting this to IProduct, but is there an elegant way to figure out what type to use here? 
      // I have to pass the serializer here because the serializer can "map" IProduct and several of its "child" types to its implementation 
      param.data = (param.data as JObject).ToObject(typeof(IProduct), serializer); 
      return param; 
     } 

     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
     { 
      // Serialization's no problem 
      serializer.Serialize(writer, value); 
     } 
    } 

正如我在代碼註釋中提到的那樣,我很困惑的部分是如何確定原始對象基於原始JSON的類型。有沒有人有建議,這樣做的非醜惡的方式?

+3

也許'新JsonSerializerSettings(){TypeNameHandling = ..... 。} –

+1

@LB謝謝,這似乎正是我所需要的 - 甚至不需要自定義轉換器。 – EJoshuaS

+0

@ L.B如果你作爲回答發佈,我會很樂意接受/ upvote – EJoshuaS

回答

1

感謝@ L.B。在這一個 - 我有點尷尬錯過了這一點,但我需要做的是

new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Objects } 

無需自定義轉換器。

我現在就留下來,以防其他人發現它有用。

0

c#中美麗的新東西之一是新的聲明類型dynamic。這與在JavaScript中聲明var(如果您熟悉)基本相同。

你的類將是:

public class Parameter 
{ 
    public dynamic data { get; set; } 
} 

現在在代碼中,我可以創建它的一個實例,並使用它,但是我想:

Parameter param = new Parameter(); 
string foo = JsonConvert.SerializeObject(some_object); 

// If you know the object type (in this case the object type is IProduct) 
param.data = JsonConvert.DeserializeObject<IProduct>(foo); 

// If you don't know the object type 
param.data = JsonConvert.DeserializeObject<ExpandoObject>(foo, new ExpandoObjectConverter()); 

在Expando對象是一個C#類,允許您創建允許您調用任何方法的動態對象,並在運行時對其進行評估。

例如

dynamic foo = new ExpandoObject(); 
// Creates a member variable named bar 
foo.bar = "Hello, World!"; 
// Throws an runtime error because bar2 is undefined 
Console.WriteLine(foo.bar2); 

我不知道這是不是你的問題,但它有助於反正知道:)

相關問題