2013-10-03 2 views
2

나는 내가 JSON으로 API에서 보내는이 ObjectJsonConvert.DeserializeObject를 사용하여 파생 개체의 목록을 역 직렬화하는

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

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

를하고 난 내 클라이언트 응용 프로그램에서 역 직렬화. 내가없는 것

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로 serialize하거나 de-serialize하는 사용자 지정 변환기를 작성했습니다. (1과 0이나 T와 F처럼) 나는 newtonsoft를 좋아해서 당신의 질문에 관심이 있었지만 해결책을 제시하기 전에 답을했다. :피 – CodeChops