2010-02-11 15 views
165

C'è un modo semplice per popolare il mio oggetto C# con l'oggetto JSON passato tramite AJAX?Come convertire l'oggetto JSON nell'oggetto Custom C#?

// Questo è l'oggetto JSON passato a C# WEBMETHOD dalla pagina utilizzando JSON.stringify

{ 
    "user" : { 
       "name" : "asdf", 
       "teamname" : "b", 
       "email" : "c", 
       "players" : ["1", 
           "2"] 
      } 
} 

// C# WebMetod che riceve l'oggetto JSON

[WebMethod] 
public static void SaveTeam(Object user) 
{ 

} 

// C# classe che rappresenta la struttura dell'oggetto dell'oggetto JSON passato al WebMethod

public class User 
{ 
    public string name { get; set; } 
    public string teamname { get; set; } 
    public string email { get; set; } 
    public Array players { get; set; } 
} 
+51

Vorrei aggiungere che è possibile utilizzare http://json2csharp.com per generare le vostre classi C# per voi. Divulgazione completa: ho creato questo sito. – JonathanK

+0

Controlla questo http://stackoverflow.com/questions/22191167/convert-json-string-to-c-sharp-object-list –

+0

@JonathanK Sei il mio salvatore! – Matheno

risposta

162

Un buon modo di utilizzare JSON in C# è con JSON.NET

Quick Starts & API Documentation da JSON.NET - Official site aiuta a lavorare con esso.

Un esempio di come usarlo:

public class User 
{ 
    public User(string json) 
    { 
     JObject jObject = JObject.Parse(json); 
     JToken jUser = jObject["user"]; 
     name = (string) jUser["name"]; 
     teamname = (string) jUser["teamname"]; 
     email = (string) jUser["email"]; 
     players = jUser["players"].ToArray(); 
    } 

    public string name { get; set; } 
    public string teamname { get; set; } 
    public string email { get; set; } 
    public Array players { get; set; } 
} 

// Use 
private void Run() 
{ 
    string json = @"{""user"":{""name"":""asdf"",""teamname"":""b"",""email"":""c"",""players"":[""1"",""2""]}}"; 
    User user = new User(json); 

    Console.WriteLine("Name : " + user.name); 
    Console.WriteLine("Teamname : " + user.teamname); 
    Console.WriteLine("Email : " + user.email); 
    Console.WriteLine("Players:"); 

    foreach (var player in user.players) 
     Console.WriteLine(player); 
} 
+3

Funziona come un campione, ma cosa succede se ho più elementi nel mio json e voglio creare un elenco di oggetti? – Djeroen

+0

@Djeroen: vedo due modi per farlo. Se gli elementi non sono raggruppati, prova a trovare un modo per dividere la stringa e ripetere il processo in un ciclo. Se sono raggruppati crea un oggetto di oggetti – user1011138

+0

Preferisco quello di cui si parla in altre risposte .. IMHO. – RayLoveless

47

Dato il vostro codice di esempio, non si dovrebbe bisogno di fare altro.

Se si passa quella stringa JSON al metodo Web, esso analizzerà automaticamente la stringa JSON e creerà un oggetto utente popolato come parametro per il metodo SaveTeam.

In generale, tuttavia, è possibile utilizzare la classe JavascriptSerializer come di seguito, o per una maggiore flessibilità, utilizzare uno dei vari framework Json disponibili (Jayrock JSON è uno dei migliori) per una facile manipolazione JSON.

JavaScriptSerializer jss= new JavaScriptSerializer(); 
User user = jss.Deserialize<User>(jsonResponse); 
+1

Penso che sia necessario utilizzare un tipo ienumerable (quindi in questo esempio Elenco ) – Dragouf

+0

Come possiamo deserializzare se contiene il modello di sottoview – SrinivasNaidu

+1

Per coloro che cercano è necessario fare riferimento all'assembly 'System.Web.Extensions' e aggiungere un' System.Web.Script.Serialization' per ottenere il 'JavaScriptSerializer', ma una volta fatto, questo sembra il modo più pulito per deserializzare le tue stringhe' json' in classi concrete C#. –

1

JSON.Net è la soluzione migliore, ma, a seconda della forma degli oggetti e se ci sono dipendenze circolari, è possibile utilizzare JavaScriptSerializer o DataContractSerializer.

86

Per mantenere aperte le opzioni, se si utilizza .NET 3.5 o versioni successive, ecco un esempio completo che è possibile utilizzare direttamente dal framework utilizzando Generics. Come altri hanno già detto, se non si tratta solo di oggetti semplici, dovresti davvero usare JSON.net.

public static string Serialize<T>(T obj) 
{ 
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType()); 
    MemoryStream ms = new MemoryStream(); 
    serializer.WriteObject(ms, obj); 
    string retVal = Encoding.UTF8.GetString(ms.ToArray()); 
    return retVal; 
} 

public static T Deserialize<T>(string json) 
{ 
    T obj = Activator.CreateInstance<T>(); 
    MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)); 
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType()); 
    obj = (T)serializer.ReadObject(ms); 
    ms.Close(); 
    return obj; 
} 

Avrete bisogno di:

using System.Runtime.Serialization; 

using System.Runtime.Serialization.Json; 
+11

+1 per aggiungere le istruzioni using ... –

+0

@ChristianPayne ha! Buon punto, sì questi dovrebbero essere avvolti. Con il senno di poi, basta usare JSON.NET! – Jammin

+2

Se la classe DataContractJsonSerializer non è visibile, è necessario aggiungere un riferimento a System.Runtime.Serialization facendo clic con il pulsante destro del mouse su Riferimenti nella soluzione, selezionare la scheda .NET e selezionare System.Runtime.Serialization – DanKodi

5

Utilizzando JavaScriptSerializer() è meno rigida rispetto alla soluzione generica offerta: public static T Deserialize (stringa JSON)

che potrebbe tornare utile quando si passa json al server che non corrisponde esattamente alla definizione dell'oggetto che si sta tentando di convertire.

4
public static class Utilities 
{ 
    public static T Deserialize<T>(string jsonString) 
    { 
     using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString))) 
     {  
      DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T)); 
      return (T)serializer.ReadObject(ms); 
     } 
    } 
} 

ulteriori informazioni visitare il seguente link http://ishareidea.blogspot.in/2012/05/json-conversion.html

Chi DataContractJsonSerializer Class si può leggere here.

12

Si tratta di uno strumento molto utile che crea modelli di oggetti C# * da JSON: http://json2csharp.com

+0

Um - la tua terminologia è un po 'spenta. Quando ho letto "C# object" ho pensato che intendessi ".Net object", come se fosse stato fatto in fase di runtime. Ma no, cosa intendi dire "dichiarazioni di classe di classe C#". – RenniePet

29

I seguenti 2 esempi fare uso di entrambi i

  1. JavaScriptSerializer sotto System.Web.Script.Serialization O
  2. Json.Decode sotto System.Web.Helpers

Esempio 1: usando System.Web.Script.Serialization

using Microsoft.VisualStudio.TestTools.UnitTesting; 
using System.Web.Script.Serialization; 

namespace Tests 
{ 
    [TestClass] 
    public class JsonTests 
    { 
     [TestMethod] 
     public void Test() 
     { 
      var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}"; 
      JavaScriptSerializer serializer = new JavaScriptSerializer(); 
      dynamic jsonObject = serializer.Deserialize<dynamic>(json); 

      dynamic x = jsonObject["user"]; // result is Dictionary<string,object> user with fields name, teamname, email and players with their values 
      x = jsonObject["user"]["name"]; // result is asdf 
      x = jsonObject["user"]["players"]; // result is object[] players with its values 
     } 
    } 
} 

Usage: JSON oggetto personalizzato C# oggetto

using System; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using System.Web.Script.Serialization; 
using System.Linq; 

namespace Tests 
{ 
    [TestClass] 
    public class JsonTests 
    { 
     [TestMethod] 
     public void TestJavaScriptSerializer() 
     { 
      var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}"; 
      User user = new User(json); 
      Console.WriteLine("Name : " + user.name); 
      Console.WriteLine("Teamname : " + user.teamname); 
      Console.WriteLine("Email : " + user.email); 
      Console.WriteLine("Players:"); 
      foreach (var player in user.players) 
       Console.WriteLine(player); 
     } 
    } 

    public class User { 
     public User(string json) { 
      JavaScriptSerializer serializer = new JavaScriptSerializer(); 
      var jsonObject = serializer.Deserialize<dynamic>(json); 
      name = (string)jsonObject["user"]["name"]; 
      teamname = (string)jsonObject["user"]["teamname"]; 
      email = (string)jsonObject["user"]["email"]; 
      players = jsonObject["user"]["players"]; 
     } 

     public string name { get; set; } 
     public string teamname { get; set; } 
     public string email { get; set; } 
     public Array players { get; set; } 
    } 
} 

Esempio 2: using System. WebHelpers

using Microsoft.VisualStudio.TestTools.UnitTesting; 
using System.Web.Helpers; 

namespace Tests 
{ 
    [TestClass] 
    public class JsonTests 
    { 
     [TestMethod] 
     public void TestJsonDecode() 
     { 
      var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}"; 
      dynamic jsonObject = Json.Decode(json); 

      dynamic x = jsonObject.user; // result is dynamic json object user with fields name, teamname, email and players with their values 
      x = jsonObject.user.name; // result is asdf 
      x = jsonObject.user.players; // result is dynamic json array players with its values 
     } 
    } 
} 

Usage: JSON oggetto personalizzato C# oggetto

using System; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 
using System.Web.Helpers; 
using System.Linq; 

namespace Tests 
{ 
    [TestClass] 
    public class JsonTests 
    { 
     [TestMethod] 
     public void TestJsonDecode() 
     { 
      var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}"; 
      User user = new User(json); 
      Console.WriteLine("Name : " + user.name); 
      Console.WriteLine("Teamname : " + user.teamname); 
      Console.WriteLine("Email : " + user.email); 
      Console.WriteLine("Players:"); 
      foreach (var player in user.players) 
       Console.WriteLine(player); 
     } 
    } 

    public class User { 
     public User(string json) { 
      var jsonObject = Json.Decode(json); 
      name = (string)jsonObject.user.name; 
      teamname = (string)jsonObject.user.teamname; 
      email = (string)jsonObject.user.email; 
      players = (DynamicJsonArray) jsonObject.user.players; 
     } 

     public string name { get; set; } 
     public string teamname { get; set; } 
     public string email { get; set; } 
     public Array players { get; set; } 
    } 
} 

Questo codice richiede l'aggiunta di System.Web.Helpers spazio dei nomi si trovano in,

% Programmi% \ Microsoft ASP.NET \ ASP. NET Web Pagine {version} \ Assemblies \ System.Web.Helpers.dll

O

% ProgramFiles (x86)% \ Microsoft ASP.NET \ ASP.NET Web Pages {version} \ Assemblies \ System.Web.Helpers.dll

Spero che questo aiuti!

+0

Questa è un'ottima risposta, ma la cosa complicata è che con i tipi 'dynamic', non si ottiene alcun controllo di tipo vero. Ad esempio, se il tuo JSON contiene "Nome": "Ahmed" e digita "Nome" nel tuo codice C#, si tratta di un errore di runtime (bleh). – Jess

+0

Grazie! Si prega di aggiornare la risposta per affermare che per l'Esempio 1, è necessario fare riferimento a System.Web.Extensions.dll –

+1

super grande risposta, la digitazione dinamica funziona anche con json.net v6.0.6! – stackuser83

92

Dal momento che noi tutti amiamo un codice liners

Newtonsoft è più veloce di java script serializzatore. ... questo dipende dal pacchetto NuGet di Newtonsoft, che è popolare e migliore del serializzatore predefinito.

se abbiamo classe quindi utilizzare di seguito.

Mycustomclassname oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<Mycustomclassname>(Json Object); 

nessuna classe quindi utilizzare dinamica

var oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(Json Object); 
1

JavaScript Serializer: richiede using System.Web.Script.Serialization;

public class JavaScriptSerializerDeSerializer<T> 
{ 
    private readonly JavaScriptSerializer serializer; 

    public JavaScriptSerializerDeSerializer() 
    { 
     this.serializer = new JavaScriptSerializer(); 
    } 

    public string Serialize(T t) 
    { 
     return this.serializer.Serialize(t); 
    } 

    public T Deseralize(string stringObject) 
    { 
     return this.serializer.Deserialize<T>(stringObject); 
    } 
} 

contratto dati Serializer: richiede using System.Runtime.Serialization.Json; - Il tipo generico T dovrebbe essere serializzabile more on Data Contract

012.
26

Un'altra Really Simple Solution sta usando il Newtonsoft.Json libreria:

User user = JsonConvert.DeserializeObject<User>(jsonString); 
0

Piuttosto che inviare come solo un oggetto.

Creare una classe pubblica di proprietà accessibile e inviare i dati al metodo Web.

[WebMethod] 
public static void SaveTeam(useSomeClassHere user) 
{ 
} 

utilizzare gli stessi nomi dei parametri nella chiamata ajax per inviare dati.