2016-05-03 17 views
5
[DataContract] 
public class A : List<B> 
{ 
    [DataMember] 
    public double TestA { get; set; } 
} 

[DataContract] 
public class B 
{ 
    [DataMember] 
    public double TestB { get; set; } 
} 

Con il modello di cui sopra provo a serializzare il seguente oggetto:oggetto Serialize quando l'oggetto eredita dalla lista

List<A> list = new List<A>() 
{ 
    new A() { TestA = 1 }, 
    new A() { TestA = 3 } 
}; 

json = JsonConvert.SerializeObject(list); 
//json: [[],[]] 

Dove sono i miei due valori da TestA? È possibile duplicare da this thread (XML), ma voglio sapere se non c'è alcuna opzione per includere tali valori impostando qualche opzione di serializzazione JSON?

Nota: la creazione di una proprietà List<B> nella classe A invece dell'ereditarietà non è un'opzione per me.

+2

Per curiosità, perché stai facendo una lezione derivata dalla lista? È estremamente raro avere sempre bisogno di farlo. Ha molto più senso creare una classe che contenga sia una lista che una doppia anziché una lista di estensione. Vedi la domanda SO "[Perché non ereditare dall'elenco ?] (Http://stackoverflow.com/questions/21692193/why-not-inherit-from-listt)" e l'ottima risposta di Eric Lippert. –

+1

Si scopre che Json.NET non supporta le collezioni serialize come oggetti quando viene applicato '[DataContact]'. Vedi [Deserializzare un 'IEnumerable ' con '[DataContract]' applicato non funziona] (http://stackoverflow.com/questions/35778811). – dbc

+0

@dbc Risposta interessante, noto che dici * Sarebbe stato possibile aggiungere membri se la tua classe implementasse 'ICollection ' *, ma List lo implementa, un bug? –

risposta

1

Secondo le osservazioni di cui sopra ci sono due modi per ottenere un risultato corretto (grazie!):

  • L'implementazione di un personalizzato JsonConverter (see here)
  • Workarround: Creare una proprietà della classe che restituisce il articoli (see here)

in ogni caso, ereditano da List<T> è raro essere una buona soluzione (see here)

Lo ho provato con la workarround:

[JsonObject(MemberSerialization = MemberSerialization.OptIn)] 
public class A : List<B> 
{ 
    [JsonProperty] 
    public double TestA { get; set; } 

    [JsonProperty] 
    public B[] Items 
    { 
     get 
     { 
      return this.ToArray(); 
     } 
     set 
     { 
      if (value != null) 
       this.AddRange(value); 
     } 
    } 
} 

public class B 
{ 
    public double TestB { get; set; } 
} 

Questo funziona per la serializzazione e deserializzazione. Importante: Items deve essere un Array di B e non List<B>. Altrimenti la deserializzazione non funziona per Items.