2016-08-17 10 views
1

をネストされたインターフェイスのリストを解決し、私はその後、私は、私は、コンバータはIListのをマッピングするために取得することができますどのように以下のクラスの&インタフェースJSON.NETは、具体的なクラスに

[DataContract] 
public class Health : IHealth 
{ 
    [DataMember(Name = "status")] 
    public string Status { get; set; } 
    [DataMember(Name = "alerts")] 
    [JsonConverter(typeof(ConcreteTypeConverter<List<Alert>>))] 
    public IList<IAlert> Alerts { get; set; } 
} 
[DataContract] 
public class Alert : IAlert 
{ 
    [DataMember(Name = "code")] 
    public string Code { get; set; } 
} 
public interface IAlert 
{ 
    string Code { get; set; } 
} 
public interface IHealth 
{ 
    string Status { get; set; } 
    IList<IAlert> Alerts { get; set; } 
} 

を持つカスタムコンバータ

public class ConcreteTypeConverter<T> : JsonConverter 
    { 
     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<T>(reader); 
     } 

     public override bool CanConvert(Type objectType) 
     { 
      return true; 
     } 
    } 

を持っていますリストに?

現在のコードは、あなたの問題は、コンバータではありません

Unable to cast object of type 'System.Collections.Generic.List`1[xxx.Services.xxx.New.Alert]' to type 'System.Collections.Generic.IList`1[xxx.Services.xxx.Configuration.Model.New.IAlert]'. 
+0

をあなたが名前空間の異なる部分を「アウトX-ED」しました例外メッセージ内の 'Alert'クラスの彼らは実際に同じですか、あるいは異なっていますか? –

+0

彼らは異なっています。最初は具象クラスであり、次はコンクリートクラスが継承するインターフェースです。両方とも2つの別々のプロジェクトに入っています。 –

+0

それは私が疑ったものです。ガレヌスのトップのリンクはなぜ私が知りたかったのかを説明しています:) –

答えて

3

、それは.NET型システムのスローされます。 はIList<IAlert>にキャストすることができず、IList<Alert>にのみキャストすることができます。これは、IList<T>が共変ではないためです(see explanation hereなど)。

あなたは何ができるか、コレクションアイテムの種類の間の変換の世話をするあなたのコレクションのプロパティに指定されたコンバータ、書いている:

public class ConcreteCollectionTypeConverter<TCollection, TItem, TBaseItem> : JsonConverter 
    where TCollection : ICollection<TBaseItem>, new() 
    where TItem : TBaseItem 
{ 
    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) 
    { 
     var collection = new TCollection(); 
     var items = serializer.Deserialize<IEnumerable<TItem>>(reader); 

     foreach (var item in items) 
     { 
      collection.Add(item); 
     } 

     return collection; 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(ICollection<TBaseItem>).IsAssignableFrom(objectType); 
    } 
} 

[DataContract] 
public class Health : IHealth 
{ 
    [DataMember(Name = "status")] 
    public string Status { get; set; } 
    [DataMember(Name = "alerts")] 
    [JsonConverter(
     typeof(ConcreteCollectionTypeConverter<List<IAlert>, Alert, IAlert>))] 
    public IList<IAlert> Alerts { get; set; } 
} 
+0

ありがとうございました。このカスタムコンバータは私にとってこのまったく同じ問題を解決しました –

関連する問題