2011-09-20 14 views
15

Ho letto dal DB un lungo json. Voglio solo un attributo di quel json.Posso deserializzare JSON nel tipo anonimo in C#?

Ho due opzioni: a. Crea un'interfaccia per quel json e deserializza su quell'interfaccia. (È eccessivo, perché ho bisogno di un solo attributo?) b. Trova la sottostringa che mi serve (regex?)

quale preferisci?

aggiornamento: sto usando .NET 3.5

risposta

26

Perché non deserializzare utilizzando JSON.NET s' approccio 'LINQ to JSON'(JObject, ecc) e basta chiedere per il valore necessario per nome?

Questo è sufficientemente dinamico in modo non è necessario creare un'interfaccia per tutto, ma è molto meno fragile rispetto all'utilizzo di una regex.

JObject json = JObject.Parse(text); 
JToken value = json["foo"]["bar"]; 

(credo JSON.NET anche di dynamic in .NET 4 sostegno, ma non c'è particolare bisogno di usarlo qui.)

2

On .NET 4:

si può fare qualcosa tipo di come ciò che si vuole meno la necessità di regolare (e non si dovrebbe usare espressioni regolari per qualcosa di simile!) utilizzando la funzione dynamic di C# 4.0 descritto qui: http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx

l'unico inconveniente è che non è possibile garantire che cos'è l'e la struttura di xact dell'oggetto è.

La ripresa è che invece di accesso ai membri via yourDynamicObject['blah'], è il più anatra-tipo-ish yourDynamicObject.blah

On .NET 3.5:

È possibile utilizzare Json.NET: http://json.codeplex.com/

18

Regex deve essere assolutamente fuori discussione. Dimenticalo, è come se non fosse mai esistito.

Creare e lavorare con tipi forti è una buona cosa e probabilmente il modo in cui andrei.

Ma se si vuole, si potrebbe anche usare dynamic:

class Program 
{ 
    static void Main() 
    { 
     var json = "{ 'foo': { 'bar': 'bar value', 'baz': [ 1, 2, 3 ] } }"; 
     var serializer = new JavaScriptSerializer(); 
     dynamic value = serializer.DeserializeObject(json); 
     Console.WriteLine(value["foo"]["baz"][1]); 
    } 
} 

stampe 2 sulla console.

+0

Sto usando C# 3.5 Non credo che ci sia un tipo dinamico. destra ? –

+2

@Elad Benda, no non c'è. Bene, allora potresti usare [Json.NET] (http://json.codeplex.com/) che offre una sintassi simile. –

0

Dipende.

L'opzione A è il modo più rigoroso, disciplinato e formale. Eppure, come hai detto tu, potrebbe essere eccessivo. Quanto è grasso quel json? A lungo termine, l'opzione A lascia la futura possibilità potenziale che potrebbe essere necessario utilizzare più di una proprietà.

L'opzione B è decisamente più informale e diretta. Funzionerà sicuramente oggi, ma potrebbe richiedere una soluzione diversa in futuro.

Quindi, forse si vorrebbe racchiudere l'intero processo in un metodo per nascondere l'implementazione dal client chiamante. Restituisci il tuo oggetto personalizzato con solo la proprietà solitaria popolata. Quindi, se si presenta la necessità in futuro, è possibile modificare il metodo per utilizzare la deserializzazione di inclinazione completa.

Nota: non penso che la deserializzazione di un tipo anonimo in C# 3.5 sia possibile.

1

Trovare la sottostringa è un'ottimizzazione pericolosa.

Vale la pena ottimizzare il processo (rispetto a una deserializzazione JSON) e sicuro di effettuare una tale ricerca? Non possiamo rispondere allo perché dipende in gran parte dal contesto. Ma ho voglia di dire NO perché è ovviamente in cerca di guai: anche se funziona ora, potrebbe rompersi in futuro quando la struttura o il contenuto dell'oggetto cambierà.

1

Vecchio thread, ma ecco un altro metodo su .NET 3.5: è possibile eseguire il cast dell'oggetto restituito da DeserializeObject su un dizionario < String, Object >. È la stessa soluzione con la parola chiave dinamica .NET 4.0:

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
Object obj = serializer.DeserializeObject("{ 'name': 'vinicius fonseca', 'age': 31 }"); 
Dictionary<String, Object> ret = (Dictionary<String, Object>)obj; 
Console.WriteLine(ret["name"].GetType().Name); // Output: String 
Console.WriteLine(ret["name"].ToString()); // Output: vinicius fonseca 
Console.WriteLine(ret["age"].GetType().Name); // Output: Int32 
Console.WriteLine(ret["age"].ToString()); // Output: 31 

Spero che aiuti qualcuno.

saluti

0

si può fare:

var result = JsonConvert.DeserializeAnonymousType(json, new { Foo="", Bar=""}); 

Ciò restituirà un oggetto dinamico con i campi definiti.

+0

Potresti per favore elaborare più la tua risposta aggiungendo un po 'più di descrizione della soluzione che fornisci? – abarisone

Problemi correlati