2013-10-03 34 views
2

我有這樣的對象使用JsonConvert.DeserializeObject反序列化派生對象的列表

public class ConversationAPI 
{ 
    [JsonProperty(PropertyName = "lU")] 
    public DateTime LastUpdated { get; set; } 

    [JsonProperty(PropertyName = "m", TypeNameHandling = TypeNameHandling.All)] 
    public List<Message> Messages { get; set; } 
} 

這是我從API爲JSON發送和我在客戶端應用程序序列化。

The List<Message> Messages property contains either 

[Serializable] 
    public class Message 
    { 
     [JsonProperty(PropertyName = "t")] 
     public string Text { get; set; } 

     [JsonProperty(PropertyName = "ty")] 
     public MessageType Type { get; set; } 
    } 

[Serializable] 
    public class DerivedMessage : Message 
    { 
     [JsonProperty(PropertyName = "sos")] 
     public string SomeOtherStuff{ get; set; } 
    } 

我似乎無法能夠反序列化派生類型的數組。 我已經試過這

var settings = new JsonSerializerSettings 
        { 
         TypeNameHandling = TypeNameHandling.All, 
         TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full 
        }; 
var conversation = JsonConvert.DeserializeObject<ConversationResponse>(response.Content, settings); 

我想提示列表有兩個消息DerivedMessage對象。

任何想法? 謝謝

回答

2

找到了解決方案。我使用了自定義轉換器

public class MessageConverter : JsonCreationConverter<ConversationAPI.Message> 
{ 
    private const string SomeOtherStuffField = "sos"; 

    protected override ConversationAPI.Message Create(Type objectType, JObject jObject) 
    { 
     if (FieldExists(SomeOtherStuffField , jObject)) 
     { 
      return new ConversationAPI.DerivedMessage(); 
     } 

     return new ConversationAPI.Message(); 
    } 

    private bool FieldExists(string fieldName, JObject jObject) 
    { 
     return jObject[fieldName] != null; 
    } 
} 

public abstract class JsonCreationConverter<T> : JsonConverter 
{ 
    /// <summary> 
    /// Create an instance of objectType, based properties in the JSON object 
    /// </summary> 
    /// <param name="objectType">type of object expected</param> 
    /// <param name="jObject">contents of JSON object that will be deserialized</param> 
    /// <returns></returns> 
    protected abstract T Create(Type objectType, JObject jObject); 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(T).IsAssignableFrom(objectType); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     // Load JObject from stream 
     JObject jObject = JObject.Load(reader); 

     // Create target object based on JObject 
     T target = Create(objectType, jObject); 

     // Populate the object properties 
     serializer.Populate(jObject.CreateReader(), target); 

     return target; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

感謝您發佈解決方案。不錯的工作。 – CodeChops

+0

對其他人也很好用:) – Mihai

+0

我寫了一個自定義轉換器,將許多變體序列化或反序列化爲true或false。 (比如1和0或者T和F)我喜歡牛頓軟件,所以我對你的問題感興趣,但是你在我可以把解決方案放在一起之前就已經回答了! :P – CodeChops