2012-07-11 18 views
8

mi hanno una struttura JSON che sembra qualcosa di simile:deserializzazione JSON in uno dei tanti C# sottoclassi

"list":[ 
    { 
    "type":"link", 
    "href":"http://google.com" 
    }, 
    { 
    "type":"image", 
    "src":"http://google.com/logo.png" 
    }, 
    { 
    "type":"text", 
    "text":"some text here" 
    }, 
] 

Vorrei deserializzare questo in un elenco di oggetti, dove ogni oggetto è una sottoclasse di una base classe. Ogni elemento nella lista ha proprietà differenti (href, src, text), quindi non posso usare la stessa classe per raggiungerne una. Invece vorrei tre sottoclassi di una classe generale. La proprietà type di ciascun elemento nell'elenco JSON può essere utilizzata per decidere quale sottoclasse utilizzare. Quindi, ad esempio, potrei avere le seguenti classi

public Item{ 
    public string type {get; set;} 
} 
public LinkItem : Item { 
    public string href {get; set;} 
} 
public ImageItem : Item { 
    public string src {get; set;} 
} 
public TextItem : Item { 
    public string text {get; set;} 
} 

C'è un modo per farlo? O c'è un modo migliore per deserializzare un elenco di tipi di oggetti eterogenei?

EDIT:

Sto usando json.net dal modo in cui

+0

Come creare una classe con tutte le proprietà. Deserializza per ottenere un elenco di tali istanze di classe. Quindi filtrare in base al tipo e proiettare le proprietà necessarie per creare le istanze specializzate. Suppongo che questo sia ciò che stai facendo attualmente, e cerchi un modo ancora migliore? –

+0

Man mano che l'applicazione aumenta la complessità dei singoli elementi potrebbe aumentare e sembra una cattiva idea avere una classe base con tutte le proprietà possibili. Quello che sto considerando è l'utilizzo di un oggetto anonimo e quindi la creazione di un'istanza successiva in base al tipo. – Marius

+0

Non intendevo una classe base. Stavo pensando più alla classe di livello intermedio che ha tutte le opzioni possibili. Da un elenco di oggetti dto, puoi modellare i tuoi oggetti specializzati richiesti. In questo modo, il tuo dominio non deve essere confuso con i problemi di serializzazione. Detto questo, potresti usare l'oggetto dinamico? Non pensavo che i tipi anonimi potessero permettervi di non definire certe proprietà ... Come nelle proprietà del primo oggetto anon deserializzato non sono le stesse proprietà che avrà il secondo oggetto anon deserializzato. –

risposta

1

Come suggerito @AmithGeorge, è possibile utilizzare un oggetto dynamic per analizzare dinamicamente l'oggetto JSON. È possibile utilizzare this great dynamic class for JSON by Shawn Weisfeld. Here is his blog explaining how he do it.

JavaScriptSerializer jss = new JavaScriptSerializer(); 
jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() }); 

dynamic glossaryEntry = jss.Deserialize(json, typeof(object)) as dynamic; 

Console.WriteLine("glossaryEntry.glossary.title: " + glossaryEntry.glossary.title); 
Console.WriteLine("glossaryEntry.glossary.GlossDiv.title: " + glossaryEntry.glossary.GlossDiv.title); 
Console.WriteLine("glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.ID: " + glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.ID); 
Console.WriteLine("glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.para: " + glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.para); 
foreach (var also in glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso) 
{ 
    Console.WriteLine("glossaryEntry.glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso: " + also); 
} 
+0

Il link è morto . Riesci a trovare e ripubblicare? - Grazie! –

+0

@DanVioletSagmiller Mi dispiace, penso che abbia già rimosso il suo repository. Puoi comunque seguire le istruzioni sul mio secondo [collegamento] (http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx) anche se. –

Problemi correlati