2009-07-30 10 views
12
List<User> list = LoadUsers(); 

JObject json = new JObject(); 

json["users"] = new JValue(list); 

Non sembra funzionare?Json.Net può gestire un elenco <object>?

Errore:

Could not determine JSON object type for type System.Collections.Generic.List`1 

risposta

37

Un JValue può contenere solo i valori semplici come stringhe, interi, booleani, date e simili. Non può contenere un oggetto complesso. Ho il sospetto che ciò che si vuole veramente è questo:

List<User> list = LoadUsers(); 

JObject json = new JObject(); 

json["users"] = JToken.FromObject(list); 

È possibile che convertirà l'elenco degli oggetti in un UserJArray di JObjects che rappresenta gli utenti, quindi assegnare che alla proprietà users sul nuovo JObject. È possibile confermare questo esaminando la proprietà Type di json["users"] e vedere che è Array.

Al contrario, se si fa json["users"] = new JValue(JsonConvert.SerializeObject(list)) come suggerito in un'altra risposta a questa domanda (ora cancellata), probabilmente non si otterrà il risultato che si sta cercando. Tale approccio serializzerà l'elenco di utenti in una stringa, creerà un semplice JValue e quindi assegnerà la proprietà JValue alla proprietà users su JObject. Se si esamina la proprietà Type di json["users"], si vedrà che è String. Ciò significa che, se in un secondo momento provi a convertire JObject in JSON utilizzando json.ToString(), otterrai un output con doppia serializzazione anziché il JSON che probabilmente ti aspetti.

Ecco una breve demo per illustrare la differenza:

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<User> list = new List<User> 
     { 
      new User { Id = 1, Username = "john.smith" }, 
      new User { Id = 5, Username = "steve.martin" } 
     }; 

     JObject json = new JObject(); 

     json["users"] = JToken.FromObject(list); 
     Console.WriteLine("First approach (" + json["users"].Type + "):"); 
     Console.WriteLine(); 
     Console.WriteLine(json.ToString(Formatting.Indented)); 

     Console.WriteLine(); 
     Console.WriteLine(new string('-', 30)); 
     Console.WriteLine(); 

     json["users"] = new JValue(JsonConvert.SerializeObject(list)); 
     Console.WriteLine("Second approach (" + json["users"].Type + "):"); 
     Console.WriteLine(); 
     Console.WriteLine(json.ToString(Formatting.Indented)); 
    } 

    class User 
    { 
     public int Id { get; set; } 
     public string Username { get; set; } 
    } 
} 

uscita:

First approach (Array): 

{ 
    "users": [ 
    { 
     "Id": 1, 
     "Username": "john.smith" 
    }, 
    { 
     "Id": 5, 
     "Username": "steve.martin" 
    } 
    ] 
} 

------------------------------ 

Second approach (String): 

{ 
    "users": "[{\"Id\":1,\"Username\":\"john.smith\"},{\"Id\":5,\"Username\":\"steve.martin\"}]" 
} 
+1

lavorato per me! Grazie – s0nica

+0

Grazie. Questo è esattamente ciò che ho passato tutto il giorno a cercare di capire. – Trebor

+0

perfetto, perché non è contrassegnato come risposta? – killernerd

0

ho avuto questo problema, è ora possibile utilizzare JArray per ottenere questo fatto, se si desidera solo il elementi dell'array senza nome radice.

var json = JArray.FromObject(LoadUsers()); 

Se si desidera che il nome radice della matrice JSON di essere "utenti", è possibile utilizzare

var json = new JObject { ["users"] = JToken.FromObject(LoadUsers()) }; 
Problemi correlati