Convertir une chaîne JSON en objet C #

183

Essayer de convertir une chaîne JSON en un objet en C #. En utilisant un cas de test très simple:

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

Le problème est que routes_list n'est jamais défini; c'est un objet indéfini. Des idées?

Justin
la source
1
@Greg: Je recommande en fait la JavaScriptSerializerversion over MS car elle n'acceptera rien d'autre que le formatage JSON personnalisé de WCF (par exemple, les champs de date qui ressemblent à des dates mais ne sont pas entourés de DATE () échouent lamentablement)
Brad Christie
Consultez également cet article Analyse des objets JSON avec JavascriptSerializer dans .NET , qui est en fait un excellent didacticiel.
scatmoi
Où obtenez-vous JavaScriptSerializer? Il n'est pas reconnu dans mon projet C # .NET 3.5.
B. Clay Shannon
1
@B. Clay Shannon Cela a résolu le
problème

Réponses:

127

Il semble que vous essayez de désérialiser en un objet brut. Vous pouvez créer une classe qui représente l'objet vers lequel vous convertissez. Cela serait plus utile dans les cas où vous avez affaire à des objets plus volumineux ou à des chaînes JSON.

Par exemple:

  class Test {

      String test; 

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

  }

Ensuite, votre code de désérialisation serait:

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

Plus d'informations peuvent être trouvées dans ce tutoriel: http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx

jmort253
la source
1
Mais dans l'article pointé, les propriétés automatiques sont utilisées. Cela vaut également la peine d'être mentionné.
Ivan Kochurkin
11
Désolé, mais cet exemple de code ne fonctionne pas. DeserializeObject donne une exception. Utilisez var routes_list = serializer.Deserialize <Test> ("{\" test \ ": \" some data \ "}"); au lieu. De plus, vous n'avez pas besoin de get / setTest (), et le test String doit être public. Cela ressemble plus à java qu'à C #.
dvallejo
comme l'a mentionné Dan Vallejo, c'est une solution incorrecte. Après tout, setTest (String test) ne retourne pas, ce qui est également une erreur de compilation.
Payam
1
Peut également utiliser ceci: json_serializer.Deserialize <Test> ("{\" test \ ": \" some data \ "}"); // au lieu de (Test) json_serializer .....
Bashar Abu Shamaa
1
Si vous n'êtes pas sûr du format de votre objet de classe, essayez ce lien . Il traduit votre chaîne Json dans les bonnes classes. M'a fait gagner beaucoup de temps!
jade290
231

Ou, vous pouvez utiliser la bibliothèque Newtownsoft.Json comme suit:

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

Test votre type d'objet qui correspond à votre chaîne JSON.

tripletdad99
la source
3
C'est si facile et j'ai longtemps réfléchi à la façon de procéder.
maracuja-juice
58

Vous ne voulez probablement pas simplement déclarer routes_list comme un objecttype. Il n'a pas de propriété .test, donc vous n'allez vraiment pas récupérer un bel objet. C'est l'un de ces endroits où il serait préférable de définir une classe ou une structure, ou d'utiliser le mot-clé dynamic.

Si vous voulez vraiment que ce code fonctionne comme vous l'avez, vous devez savoir que l'objet renvoyé par DeserializeObject est un dictionnaire générique de chaîne, d'objet. Voici le code pour le faire de cette façon:

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

Si vous souhaitez utiliser le mot-clé dynamique, vous pouvez lire comment ici .

Si vous déclarez une classe ou une structure, vous pouvez appeler Deserialize au lieu de DeserializeObject comme ceci:

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);
    }
}
mattmc3
la source
Faire: json_serializer = new JavaScriptSerializer (); object routes_list = (IDictionary <string, object>) json_serializer.DeserializeObject ("{\" test \ ": \" quelques données ici \ "}"); L'obtention de 'routes_list' n'existe toujours pas dans le contexte actuel.
Justin le
1
N'utilisez pas object routes_list. Utilisez varou répétez-vous explicitement et déclarez routes_list en tant que IDictionary <string, object>.
mattmc3
31

Utilisation d'un objet dynamique avec JavaScriptSerializer.

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

//test Result = "some data"
İbrahim Özbölük
la source
19

Newtonsoft est plus rapide que le sérialiseur de script java. ... celui-ci dépend du package Newtonsoft NuGet, qui est populaire et meilleur que le sérialiseur par défaut.

solution de code en une ligne.

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

Myclass oMyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<Myclass>(Jsonstring);
MSTdev
la source
15

Voici un cours simple que j'ai bricolé à partir de divers articles ... Il a été testé pendant environ 15 minutes, mais semble fonctionner pour mes besoins. Il utilise JavascriptSerializerpour faire le travail, qui peut être référencé dans votre application à l'aide des informations détaillées dans cet article .

Le code ci-dessous peut être exécuté dans LinqPad pour le tester en:

  • Faites un clic droit sur l'onglet de votre script dans LinqPad et choisissez "Propriétés de la requête"
  • Référence à «System.Web.Extensions.dll» dans «Références supplémentaires»
  • Ajout d'un "Additional Namespace Imports" de "System.Web.Script.Serialization".

J'espère que ça aide!

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;
  }
}
Brad Parks
la source
14

Vous pouvez facilement répondre à vos besoins en utilisant la bibliothèque Newtonsoft.Json. J'écris l'exemple ci-dessous pour y jeter un coup d'œil.

Classe pour le type d'objet que vous recevez:

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

}

Code:

static void Main(string[] args)
{

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

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

      Console.ReadKey();
}

c'est un moyen très simple d'analyser votre json.

Mirza danois Baig
la source
11

Comme tripletdad99 l'a dit

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

mais si vous ne voulez pas créer un objet supplémentaire, vous pouvez le créer à la Dictionaryplace

var result = JsonConvert.DeserializeObject<Dictionary<string, string>>(json_serializer);
stanimirsp
la source
Ceci est utile, lorsque vous passez ensuite des paramètres à Url.Action (action, contrôleur, résultat)
Lapenkov Vladimir
8

ajoutez ce ddl pour faire référence à votre projet: System.Web.Extensions.dll

utilisez cet espace de noms: 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);
Thulasiram
la source
6

Copiez votre Json et collez-le dans la zone de texte sur json2csharp et cliquez sur le bouton Générer.

Une classe cs sera générée en utilisant ce fichier cs comme ci-dessous

var generatedcsResponce = JsonConvert.DeserializeObject(yourJson);

RootObjectest le nom du fichier cs généré ;

Islam
la source
4

Un autre moyen rapide et facile de semi-automatiser ces étapes consiste à:

  1. prenez le JSON que vous souhaitez analyser et collez-le ici: https://app.quicktype.io/ . Changez la langue en C # dans la liste déroulante.
  2. Mettez à jour le nom en haut à gauche avec le nom de votre classe, il est par défaut "Bienvenue".
  3. Dans Visual Studio, accédez à Site Web -> Gérer les packages et utilisez NuGet pour ajouter Json.Net à partir de Newtonsoft.
  4. app.quicktype.io a généré des méthodes de sérialisation basées sur Newtonsoft. Alternativement, vous pouvez maintenant utiliser du code comme:

    Client WebClient = nouveau WebClient ();

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

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

Jason Hitchings
la source
Lien plus valide
Myles J
Merci Myles J, j'ai mis à jour un nouveau site qui semble bien fonctionner.
Jason Hitchings
0

Convertissez une chaîne JSON en un objet en C #. En utilisant le cas de test ci-dessous ... cela a fonctionné pour moi. Ici, " MenuInfo " est mon objet de 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);
Bhaskar
la source
0

Vous devez d'abord inclure une bibliothèque comme:

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);
}
Muhammad Zahid
la source