Converti stringa JSON in oggetto C #


183

Prova di convertire una stringa JSON in un oggetto in C #. Utilizzando un test case davvero semplice:

JavaScriptSerializer json_serializer = new JavaScriptSerializer();
object routes_list = json_serializer.DeserializeObject("{ \"test\":\"some data\" }");

Il problema è che route_list non viene mai impostato; è un oggetto indefinito. Qualche idea?


1
@Greg: in realtà raccomando la JavaScriptSerializerversione over MS in quanto non accetterà nient'altro che la formattazione JSON personalizzata di WCF (ad esempio i campi di date che sembrano date ma non sono racchiusi in DATA () falliscono miseramente)
Brad Christie,

Inoltre, guarda questo oggetti Parsing JSON con JavascriptSerializer nell'articolo .NET , che in realtà è un ottimo tutorial.
scatmoi,

Dove stai ottenendo JavaScriptSerializer? Non è riconosciuto nel mio progetto C # .NET 3.5.
B. Clay Shannon,

1
@B. Argilla Shannon Questo risolto per me stackoverflow.com/questions/7000811/...
Fuzzybear

Risposte:


127

Sembra che tu stia cercando di deserializzare un oggetto grezzo. È possibile creare una classe che rappresenta l'oggetto in cui si sta convertendo. Ciò sarebbe molto utile nei casi in cui hai a che fare con oggetti più grandi o stringhe JSON.

Per esempio:

  class Test {

      String test; 

      String getTest() { return test; }
      void setTest(String test) { this.test = test; }

  }

Quindi il tuo codice di deserializzazione sarebbe:

   JavaScriptSerializer json_serializer = new JavaScriptSerializer();
   Test routes_list = 
          (Test)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");

Ulteriori informazioni sono disponibili in questo tutorial: http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx


1
Ma nell'articolo appuntito vengono utilizzate le autoproperties. Vale anche la pena menzionarlo.
Ivan Kochurkin,

11
Spiacenti, ma questo esempio di codice non funziona. DeserializeObject dà un'eccezione. Usa var route_list = serializer.Deserialize <Test> ("{\" test \ ": \" alcuni dati \ "}"); anziché. Inoltre, non è necessario che get / setTest () e String test siano pubblici. Sembra più Java che C #.
dvallejo,

come ha detto Dan Vallejo, questa è una soluzione errata. Dopotutto, setTest (String test) non ritorna, il che è anche errore di compilazione.
Payam,

1
Puoi anche usare questo: json_serializer.Deserialize <Test> ("{\" test \ ": \" alcuni dati \ "}"); // invece di (Test) json_serializer .....
Bashar Abu Shamaa,

1
Se non si è sicuri del formato per l'oggetto classe, provare questo collegamento . Traduce la tua stringa Json nelle classi giuste. Mi hai salvato un sacco di tempo!
jade290,

231

In alternativa, è possibile utilizzare la libreria Newtownsoft.Json come segue:

using Newtonsoft.Json;
...
var result = JsonConvert.DeserializeObject<T>(json);

Dov'è Til tipo di oggetto che corrisponde alla stringa JSON.


3
È così facile e ho pensato così tanto a come farlo.
succo di maracuja,

58

Probabilmente non vuoi semplicemente dichiarare route_list come un objecttipo. Non ha una proprietà .test, quindi non hai intenzione di recuperare un oggetto carino. Questo è uno di quei posti in cui sarebbe meglio definire una classe o una struttura o utilizzare la parola chiave dinamica.

Se vuoi davvero che questo codice funzioni così come lo hai, devi sapere che l'oggetto restituito da DeserializeObject è un dizionario generico di stringa, oggetto. Ecco il codice per farlo in questo modo:

var json_serializer = new JavaScriptSerializer();
var routes_list = (IDictionary<string, object>)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");
Console.WriteLine(routes_list["test"]);

Se vuoi usare la parola chiave dinamica, puoi leggere come qui .

Se dichiari una classe o una struttura, puoi chiamare Deserialize invece di DeserializeObject in questo modo:

class MyProgram {
    struct MyObj {
        public string test { get; set; }
    }

    static void Main(string[] args) {
        var json_serializer = new JavaScriptSerializer();
        MyObj routes_list = json_serializer.Deserialize<MyObj>("{ \"test\":\"some data\" }");
        Console.WriteLine(routes_list.test);

        Console.WriteLine("Done...");
        Console.ReadKey(true);
    }
}

Fare: json_serializer = new JavaScriptSerializer (); oggetto route_list = (IDictionary <stringa, oggetto>) json_serializer.DeserializeObject ("{\" test \ ": \" alcuni dati qui \ "}"); Ottenere ancora "route_list" non esiste nel contesto attuale.
Justin

1
Non usare object routes_list. Usa varo ripeti esplicitamente te stesso e dichiara route_list come IDictionary <stringa, oggetto>.
mattmc3,

31

Utilizzo dell'oggetto dinamico con JavaScriptSerializer.

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
dynamic item = serializer.Deserialize<object>("{ \"test\":\"some data\" }");
string test= item["test"];

//test Result = "some data"

19

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

soluzione con un codice di riga.

var myclass = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(Jsonstring);

Myclass oMyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<Myclass>(Jsonstring);

15

Ecco una semplice lezione che ho messo insieme da vari post ... È stato testato per circa 15 minuti, ma sembra funzionare per i miei scopi. Usa JavascriptSerializerper fare il lavoro, a cui puoi fare riferimento nella tua app usando le informazioni dettagliate in questo post .

Il codice seguente può essere eseguito in LinqPad per testarlo:

  • Fare clic con il tasto destro sulla scheda dello script in LinqPad e scegliere "Proprietà della query"
  • Riferimenti a "System.Web.Extensions.dll" in "Riferimenti aggiuntivi"
  • Aggiunta di "Importazioni di spazi dei nomi aggiuntivi" di "System.Web.Script.Serialization".

Spero che sia d'aiuto!

void Main()
{
  string json = @"
  {
    'glossary': 
    {
      'title': 'example glossary',
        'GlossDiv': 
        {
          'title': 'S',
          'GlossList': 
          {
            'GlossEntry': 
            {
              'ID': 'SGML',
              'ItemNumber': 2,          
              'SortAs': 'SGML',
              'GlossTerm': 'Standard Generalized Markup Language',
              'Acronym': 'SGML',
              'Abbrev': 'ISO 8879:1986',
              'GlossDef': 
              {
                'para': 'A meta-markup language, used to create markup languages such as DocBook.',
                'GlossSeeAlso': ['GML', 'XML']
              },
              'GlossSee': 'markup'
            }
          }
        }
    }
  }

  ";

  var d = new JsonDeserializer(json);
  d.GetString("glossary.title").Dump();
  d.GetString("glossary.GlossDiv.title").Dump();  
  d.GetString("glossary.GlossDiv.GlossList.GlossEntry.ID").Dump();  
  d.GetInt("glossary.GlossDiv.GlossList.GlossEntry.ItemNumber").Dump();    
  d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef").Dump();   
  d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso").Dump(); 
  d.GetObject("Some Path That Doesnt Exist.Or.Another").Dump();   
}


// Define other methods and classes here

public class JsonDeserializer
{
  private IDictionary<string, object> jsonData { get; set; }

  public JsonDeserializer(string json)
  {
    var json_serializer = new JavaScriptSerializer();

    jsonData = (IDictionary<string, object>)json_serializer.DeserializeObject(json);
  }

  public string GetString(string path)
  {
    return (string) GetObject(path);
  }

  public int? GetInt(string path)
  {
    int? result = null;

    object o = GetObject(path);
    if (o == null)
    {
      return result;
    }

    if (o is string)
    {
      result = Int32.Parse((string)o);
    }
    else
    {
      result = (Int32) o;
    }

    return result;
  }

  public object GetObject(string path)
  {
    object result = null;

    var curr = jsonData;
    var paths = path.Split('.');
    var pathCount = paths.Count();

    try
    {
      for (int i = 0; i < pathCount; i++)
      {
        var key = paths[i];
        if (i == (pathCount - 1))
        {
          result = curr[key];
        }
        else
        {
          curr = (IDictionary<string, object>)curr[key];
        }
      }
    }
    catch
    {
      // Probably means an invalid path (ie object doesn't exist)
    }

    return result;
  }
}

14

Puoi soddisfare facilmente le tue esigenze utilizzando la libreria Newtonsoft.Json. Sto scrivendo il seguente esempio dare un'occhiata in esso.

Classe per il tipo di oggetto che ricevi:

public class User
{
    public int ID { get; set; }
    public string Name { get; set; }

}

Codice:

static void Main(string[] args)
{

      string json = "{\"ID\": 1, \"Name\": \"Abdullah\"}";

      User user = JsonConvert.DeserializeObject<User>(json);

      Console.ReadKey();
}

questo è un modo molto semplice per analizzare il tuo JSON.


11

Come diceva tripletdad99

var result = JsonConvert.DeserializeObject<T>(json);

ma se non si desidera creare un oggetto in più si può fare con il Dictionaryposto

var result = JsonConvert.DeserializeObject<Dictionary<string, string>>(json_serializer);

Questo è utile, quando passi i parametri a Url.Action (azione, controller, risultato)
Lapenkov Vladimir

8

aggiungi questo ddl per fare riferimento al tuo progetto: System.Web.Extensions.dll

usa questo spazio dei nomi: using System.Web.Script.Serialization;

public class IdName
{
    public int Id { get; set; }
    public string Name { get; set; }
}


   string jsonStringSingle = "{'Id': 1, 'Name':'Thulasi Ram.S'}".Replace("'", "\"");
   var entity = new JavaScriptSerializer().Deserialize<IdName>(jsonStringSingle);

   string jsonStringCollection = "[{'Id': 2, 'Name':'Thulasi Ram.S'},{'Id': 2, 'Name':'Raja Ram.S'},{'Id': 3, 'Name':'Ram.S'}]".Replace("'", "\"");
   var collection = new JavaScriptSerializer().Deserialize<IEnumerable<IdName>>(jsonStringCollection);

6

Copia il tuo Json e incollalo nella casella di testo su json2csharp e fai clic sul pulsante Genera.

Verrà generata una classe cs usando quel file cs come di seguito

var generatedcsResponce = JsonConvert.DeserializeObject(yourJson);

Dov'è RootObjectil nome del file cs generato ;


4

Un altro modo semplice e veloce per semi-automatizzare questi passaggi è:

  1. prendi il JSON che vuoi analizzare e incollalo qui: https://app.quicktype.io/ . Cambia la lingua in C # nel menu a discesa.
  2. Aggiorna il nome in alto a sinistra con il nome della tua classe, il valore predefinito è "Benvenuto".
  3. In Visual Studio vai al sito Web -> Gestisci pacchetti e usa NuGet per aggiungere Json.Net da Newtonsoft.
  4. app.quicktype.io ha generato metodi di serializzazione basati su Newtonsoft. In alternativa, ora puoi usare un codice come:

    WebClient client = new WebClient ();

    stringa myJSON = client.DownloadString (" https://URL_FOR_JSON.com/JSON_STUFF ");

    var myClass = Newtonsoft.Json.JsonConvert.DeserializeObject (myJSON);


Link non più valido
Myles J

Grazie Myles J, ho aggiornato un nuovo sito che sembra funzionare bene.
Jason Hitchings,

0

Converti una stringa JSON in un oggetto in C #. Utilizzando il test case di seguito ... ha funzionato per me. Qui " MenuInfo " è il mio oggetto di classe C #.

JsonTextReader reader = null;
try
{
    WebClient webClient = new WebClient();
    JObject result = JObject.Parse(webClient.DownloadString("YOUR URL"));
    reader = new JsonTextReader(new System.IO.StringReader(result.ToString()));
    reader.SupportMultipleContent = true;
}
catch(Exception)
{}

JsonSerializer serializer = new JsonSerializer();
MenuInfo menuInfo = serializer.Deserialize<MenuInfo>(reader);

0

Per prima cosa devi includere una libreria come:

using System.Runtime.Serialization.Json;

DataContractJsonSerializer desc = new DataContractJsonSerializer(typeof(BlogSite));
string json = "{\"Description\":\"Share knowledge\",\"Name\":\"zahid\"}";

using (var ms = new MemoryStream(ASCIIEncoding.ASCII.GetBytes(json)))
{
    BlogSite b = (BlogSite)desc.ReadObject(ms);
    Console.WriteLine(b.Name);
    Console.WriteLine(b.Description);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.