2013-03-14 94 views
2

我正在使用ConcreteCollectionTypeConverter反序列化IList類型的對象。我可能做起來很錯誤的,因爲我不斷收到異常「無法轉換目錄到IList的」使用Newtonsoft JSON反序列化IList對象

我的目標inteface看起來是這樣的:

[JsonObject(MemberSerialization.OptIn)] 
public IMyInterface { 

    [JsonProperty("associatedContact")] 
    [JsonConverter(typeof(ConcreteCollectionTypeConverter<IList<ISomeOtherInterface>, List<SomeOtherInterface>>))] 
    IList<ISomeOtherInterface> MyObject { get; set; } 
} 

我的目標實現是這樣的:

public MyImplementation : IMyInterface { 

    public List<SomeOtherImplementation> MyObject { get; set; } 

    public MyImplementations() { 
     MyObject = new List<SomeOtherImplementation>();   
    } 
} 

的json轉換器看起來是這樣的:

class ConcreteCollectionTypeConverter<TInterface, TImplementation> : JsonConverter where TImplementation : TInterface 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return true; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     serializer.Serialize(writer, value); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     return serializer.Deserialize<TImplementation>(reader); 
    } 
} 

我打電話給我的項目中的其他地方的反序列化方法是這樣的:

var myDeserializedObject = JsonConvert.DeserializeObject<MyImplementation>(jsonObject.ToString()); 

我上面提到的jsonObject被正確解析。

我知道這是可能的,因爲我已經看到了一個來自用戶調用SO的評論,他已經完成了它(Casting interfaces for deserialization in JSON.NET-接受的答案的第一評論)。

此方法適用於非集合項目(即使用JsonConverer(typeof(ConcreteTypeCOnverter))工作)反序列化接口類型IIterface MyObject的對象。

如果我只使用列表而不是IList,我甚至不需要類型轉換器,但我的要求是確保ICollections的使用,因爲可能存在非標準實現。

回答

1

我相信這會爲你所需要的工作:

public class ConcreteListTypeConverter<TInterface, TImplementation> : JsonConverter where TImplementation : TInterface 
{ 
    public override bool CanConvert(Type objectType) 
    { 
     return true; 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     var res = serializer.Deserialize<List<TImplementation>>(reader); 
     return res.ConvertAll(x => (TInterface) x); 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     serializer.Serialize(writer, value); 
    } 
}