Comment transformer un objet C # en chaîne JSON dans .NET?

944

J'ai des cours comme ceux-ci:

class MyDate
{
    int year, month, day;
}

class Lad
{
    string firstName;
    string lastName;
    MyDate dateOfBirth;
}

Et je voudrais transformer un Ladobjet en une chaîne JSON comme ceci:

{
    "firstName":"Markoff",
    "lastName":"Chaney",
    "dateOfBirth":
    {
        "year":"1901",
        "month":"4",
        "day":"30"
    }
}

(sans le formatage). J'ai trouvé ce lien , mais il utilise un espace de noms qui n'est pas dans .NET 4 . J'ai également entendu parler de JSON.NET , mais leur site semble être en panne pour le moment, et je ne suis pas désireux d'utiliser des fichiers DLL externes.

Existe-t-il d'autres options que la création manuelle d'un rédacteur de chaînes JSON ?

Hui
la source
2
JSON.net peut être chargé ici Une autre solution plus rapide (comme on dit - je ne l'ai pas testée moi-même) est ServiceStack.Text Je ne recommanderais pas de rouler votre propre analyseur JSON. Cela sera probablement plus lent et plus sujet aux erreurs ou vous devrez investir beaucoup de temps.
Zebi
Oui. C # a un type appelé JavaScriptSerializer
Glenn Ferrie
doublon possible de Generics / JSON JavaScriptSerializer C #
Filip Ekberg
2
Hm .. autant que je puisse voir, vous devriez pouvoir utiliser: msdn.microsoft.com/en-us/library/… qui est également en .Net 4.0 selon la page MSDN. Vous devriez pouvoir utiliser la méthode Serialize (Object obj): msdn.microsoft.com/en-us/library/bb292287.aspx Suis-je en train de manquer quelque chose? Btw. votre lien semble être un code et non un lien
Holger
Sans oublier qu'il n'a pas de dépendances sur les espaces de noms System.Web.Xyz ...
Dave Jellison

Réponses:

899

Vous pouvez utiliser la JavaScriptSerializerclasse (ajouter une référence à System.Web.Extensions):

using System.Web.Script.Serialization;
var json = new JavaScriptSerializer().Serialize(obj);

Un exemple complet:

using System;
using System.Web.Script.Serialization;

public class MyDate
{
    public int year;
    public int month;
    public int day;
}

public class Lad
{
    public string firstName;
    public string lastName;
    public MyDate dateOfBirth;
}

class Program
{
    static void Main()
    {
        var obj = new Lad
        {
            firstName = "Markoff",
            lastName = "Chaney",
            dateOfBirth = new MyDate
            {
                year = 1901,
                month = 4,
                day = 30
            }
        };
        var json = new JavaScriptSerializer().Serialize(obj);
        Console.WriteLine(json);
    }
}
Darin Dimitrov
la source
95
N'oubliez pas que Microsoft suggère d'utiliser JSON.net au lieu de cette solution. Je pense que cette réponse est devenue inappropriée. Jetez un œil à la réponse de willsteel. Source: https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx .
rzelek
9
@DarinDimitrov, vous devriez envisager d'ajouter un indice sur JSON.net. Microsoft le recommande sur JavascriptSerializer: msdn.microsoft.com/en-us/library/… Vous pouvez également ajouter un indice à msdn.microsoft.com/en-us/library/… qui est l'approche du framework inclus
Mafii
ici est l' outil en ligne pour convertir votre classesau jsonformat espoir aide quelqu'un.
shaijut
6
Pourquoi Microsoft recommanderait-il une solution tierce par rapport à la leur? Leur formulation est également très étrange: "Json.NET devrait être utilisé pour la sérialisation et la désérialisation. Fournit des fonctionnalités de sérialisation et de désérialisation pour les applications compatibles AJAX."
Protector one
1
Juste un avertissement, pour référence System.Web.Extensions, vous devez avoir ASP.NET AJAX 1.0ou ASP.NET 3.5installé sur votre système. Veuillez voir ce stackoverflow.com/questions/7723489/…
Sisir
1057

Puisque nous aimons tous les monoplaces

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

Newtonsoft.Json.JsonConvert.SerializeObject(new {foo = "bar"})

Documentation: Sérialisation et désérialisation JSON

mschmoock
la source
134
Le sérialiseur Newtonsoft est beaucoup plus rapide et plus personnalisable que intégré. Je recommande vivement de l'utiliser. Merci pour la réponse @willsteel
Andrei
8
@JosefPfleger le prix est pour le schéma JSON.NET, pas JSON.NET le sérialiseur régulier, qui est le MIT
David Cumps
1
Mes tests ont montré que Newtonsoft est plus lent que la classe JavaScriptSerializer. (.NET 4.5.2)
nemke
31
Si vous lisez la documentation MSDN pour JavaScriptSerializer , cela indique clairement que vous utilisez JSON.net.
dsghi
3
@JosefPfleger Newtionsoft JSON.net est sous licence MIT ... vous pouvez apporter des modifications et le revendre comme vous le souhaitez. Leur page de tarification concerne le support technique commercial et certains validateurs de schéma dont ils disposent.
cb88
96

Utilisez la bibliothèque Json.Net , vous pouvez la télécharger depuis Nuget Packet Manager.

Sérialisation vers Json String:

 var obj = new Lad
        {
            firstName = "Markoff",
            lastName = "Chaney",
            dateOfBirth = new MyDate
            {
                year = 1901,
                month = 4,
                day = 30
            }
        };

var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(obj);

Désérialisation en objet:

var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<Lad>(jsonString );
Gokulan PH
la source
57

Utilisez la DataContractJsonSerializerclasse: MSDN1 , MSDN2 .

Mon exemple: ICI .

Contrairement à, il peut également désérialiser en toute sécurité des objets d'une chaîne JSON JavaScriptSerializer. Mais personnellement, je préfère toujours Json.NET .

Edgar
la source
1
Je ne vois toujours aucun exemple sur cette page , mais en voici quelques-uns sur MSDN et ailleurs -> le dernier utilise des méthodes d'extension pour réaliser des lignes uniques.
Cristian Diaconescu
Oh, j'ai raté le 2e lien MSDN :)
Cristian Diaconescu
2
Il ne sérialise pas les classes simples. L'erreur a signalé "Envisagez de le marquer avec l'attribut DataContractAttribute et de marquer tous ses membres que vous souhaitez sérialiser avec l'attribut DataMemberAttribute. Si le type est une collection, envisagez de le marquer avec CollectionDataContractAttribute."
Michael Freidgeim
@MichaelFreidgeim C'est vrai, vous devez marquer les propriétés dans la classe que vous souhaitez sérialiser avec des attributs. DataContractAttribute DataMemberAttribute
Edgar
1
@MichaelFreidgeim Le meilleur dépend des exigences. Les attributs vous permettent de configurer la façon dont la propriété est sérialisée.
Edgar
24

Vous pouvez y parvenir en utilisant Newtonsoft.json. Installez Newtonsoft.json à partir de NuGet. Et alors:

using Newtonsoft.Json;

var jsonString = JsonConvert.SerializeObject(obj);
Waleed Naveed
la source
22

Wooou! Vraiment mieux en utilisant un framework JSON :)

Voici mon exemple d'utilisation de Json.NET ( http://james.newtonking.com/json ):

using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using System.IO;

namespace com.blogspot.jeanjmichel.jsontest.model
{
    public class Contact
    {
        private Int64 id;
        private String name;
        List<Address> addresses;

        public Int64 Id
        {
            set { this.id = value; }
            get { return this.id; }
        }

        public String Name
        {
            set { this.name = value; }
            get { return this.name; }
        }

        public List<Address> Addresses
        {
            set { this.addresses = value; }
            get { return this.addresses; }
        }

        public String ToJSONRepresentation()
        {
            StringBuilder sb = new StringBuilder();
            JsonWriter jw = new JsonTextWriter(new StringWriter(sb));

            jw.Formatting = Formatting.Indented;
            jw.WriteStartObject();
            jw.WritePropertyName("id");
            jw.WriteValue(this.Id);
            jw.WritePropertyName("name");
            jw.WriteValue(this.Name);

            jw.WritePropertyName("addresses");
            jw.WriteStartArray();

            int i;
            i = 0;

            for (i = 0; i < addresses.Count; i++)
            {
                jw.WriteStartObject();
                jw.WritePropertyName("id");
                jw.WriteValue(addresses[i].Id);
                jw.WritePropertyName("streetAddress");
                jw.WriteValue(addresses[i].StreetAddress);
                jw.WritePropertyName("complement");
                jw.WriteValue(addresses[i].Complement);
                jw.WritePropertyName("city");
                jw.WriteValue(addresses[i].City);
                jw.WritePropertyName("province");
                jw.WriteValue(addresses[i].Province);
                jw.WritePropertyName("country");
                jw.WriteValue(addresses[i].Country);
                jw.WritePropertyName("postalCode");
                jw.WriteValue(addresses[i].PostalCode);
                jw.WriteEndObject();
            }

            jw.WriteEndArray();

            jw.WriteEndObject();

            return sb.ToString();
        }

        public Contact()
        {
        }

        public Contact(Int64 id, String personName, List<Address> addresses)
        {
            this.id = id;
            this.name = personName;
            this.addresses = addresses;
        }

        public Contact(String JSONRepresentation)
        {
            //To do
        }
    }
}

Le test:

using System;
using System.Collections.Generic;
using com.blogspot.jeanjmichel.jsontest.model;

namespace com.blogspot.jeanjmichel.jsontest.main
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<Address> addresses = new List<Address>();
            addresses.Add(new Address(1, "Rua Dr. Fernandes Coelho, 85", "15º andar", "São Paulo", "São Paulo", "Brazil", "05423040"));
            addresses.Add(new Address(2, "Avenida Senador Teotônio Vilela, 241", null, "São Paulo", "São Paulo", "Brazil", null));

            Contact contact = new Contact(1, "Ayrton Senna", addresses);

            Console.WriteLine(contact.ToJSONRepresentation());
            Console.ReadKey();
        }
    }
}

Le résultat:

{
  "id": 1,
  "name": "Ayrton Senna",
  "addresses": [
    {
      "id": 1,
      "streetAddress": "Rua Dr. Fernandes Coelho, 85",
      "complement": "15º andar",
      "city": "São Paulo",
      "province": "São Paulo",
      "country": "Brazil",
      "postalCode": "05423040"
    },
    {
      "id": 2,
      "streetAddress": "Avenida Senador Teotônio Vilela, 241",
      "complement": null,
      "city": "São Paulo",
      "province": "São Paulo",
      "country": "Brazil",
      "postalCode": null
    }
  ]
}

Maintenant, je vais implémenter la méthode constructeur qui recevra une chaîne JSON et remplira les champs de la classe.

Jean J. Michel
la source
1
Bon article, c'est la façon la plus courante de le faire.
MatthewD
20

Un nouveau sérialiseur JSON est disponible dans l' System.Text.Jsonespace de noms. Il est inclus dans le framework partagé .NET Core 3.0 et se trouve dans un package NuGet pour les projets qui ciblent .NET Standard ou .NET Framework ou .NET Core 2.x.

Exemple de code:

using System;
using System.Text.Json;

public class MyDate
{
    public int year { get; set; }
    public int month { get; set; }
    public int day { get; set; }
}

public class Lad
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public MyDate DateOfBirth { get; set; }
}

class Program
{
    static void Main()
    {
        var lad = new Lad
        {
            FirstName = "Markoff",
            LastName = "Chaney",
            DateOfBirth = new MyDate
            {
                year = 1901,
                month = 4,
                day = 30
            }
        };
        var json = JsonSerializer.Serialize(lad);
        Console.WriteLine(json);
    }
}

Dans cet exemple, les classes à sérialiser ont des propriétés plutôt que des champs; System.Text.Jsonactuellement, le sérialiseur ne sérialise pas les champs.

Documentation:

tdykstra
la source
9

S'ils ne sont pas très gros, quel est probablement votre cas, exportez-le en JSON.

Cela le rend également portable sur toutes les plates-formes.

using Newtonsoft.Json;

[TestMethod]
public void ExportJson()
{
    double[,] b = new double[,]
        {
            { 110,  120,  130,  140, 150 },
            {1110, 1120, 1130, 1140, 1150},
            {1000,    1,   5,     9, 1000},
            {1110,    2,   6,    10, 1110},
            {1220,    3,   7,    11, 1220},
            {1330,    4,   8,    12, 1330}
        };

    string jsonStr = JsonConvert.SerializeObject(b);

    Console.WriteLine(jsonStr);

    string path = "X:\\Programming\\workspaceEclipse\\PyTutorials\\src\\tensorflow_tutorials\\export.txt";

    File.WriteAllText(path, jsonStr);
}
user8426627
la source
8

Si vous êtes dans un contrôleur Web ASP.NET MVC, c'est aussi simple que:

string ladAsJson = Json(Lad);

Je ne peux pas croire que personne n'ait mentionné cela.

micahhoover
la source
1
J'obtiens une erreur de ne pas pouvoir convertir jsonresult en chaîne.
csga5000
Il compilera avec un typage implicite: var ladAsJson = Json (Lad).
ewomack
3

Je voterais pour le sérialiseur JSON de ServiceStack:

using ServiceStack.Text

string jsonString = new { FirstName = "James" }.ToJson();

C'est également le sérialiseur JSON le plus rapide disponible pour .NET: http://www.servicestack.net/benchmarks/

James
la source
4
Ce sont là des repères très anciens. Je viens de tester les trois versions actuelles de Newtonsoft, ServiceStack et JavaScriptSerializer et actuellement Newtonsoft est la plus rapide. Ils font tous assez vite.
Michael Logutov
1
ServiceStack ne semble pas être gratuit.
joelnet
@joelnet c'est maintenant le cas, mais c'était gratuit en répondant à la question. Cependant c'est gratuit pour les petits sites, et je l'utilise toujours même s'il est payant, c'est un superbe framework.
James
Quelques repères ici, bien qu'il n'y ait pas de sérialisation en soi: docs.servicestack.net/real-world-performance
JohnLBevan
3

Utilisez le code ci-dessous pour convertir XML en JSON.

var json = new JavaScriptSerializer().Serialize(obj);
Hithesh
la source
3

Utilisez ces outils pour générer une classe C #, puis utilisez ce code pour sérialiser votre objet:

 var json = new JavaScriptSerializer().Serialize(obj);
Artem Polishchuk
la source
3

C'est aussi simple que cela (cela fonctionne aussi pour les objets dynamiques (type objet)):

string json = new
System.Web.Script.Serialization.JavaScriptSerializer().Serialize(MYOBJECT);
MarzSocks
la source
il n'y a pas de script par défaut sous web. :(
M au
Vous recherchez ceci: msdn.microsoft.com/en-us/library/…
MarzSocks
J'ai en quelque sorte essayé mais non. Script, je suppose que je devrais l'ajouter comme référence. Merci beaucoup
M au
0

Sérialiseur

 public static void WriteToJsonFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
        var contentsToWriteToFile = JsonConvert.SerializeObject(objectToWrite, new JsonSerializerSettings
        {
            Formatting = Formatting.Indented,
        });
        using (var writer = new StreamWriter(filePath, append))
        {
            writer.Write(contentsToWriteToFile);
        }
}

Objet

namespace MyConfig
{
    public class AppConfigurationSettings
    {
        public AppConfigurationSettings()
        {
            /* initialize the object if you want to output a new document
             * for use as a template or default settings possibly when 
             * an app is started.
             */
            if (AppSettings == null) { AppSettings=new AppSettings();}
        }

        public AppSettings AppSettings { get; set; }
    }

    public class AppSettings
    {
        public bool DebugMode { get; set; } = false;
    }
}

la mise en oeuvre

var jsonObject = new AppConfigurationSettings();
WriteToJsonFile<AppConfigurationSettings>(file.FullName, jsonObject);

Production

{
  "AppSettings": {
    "DebugMode": false
  }
}
dynamiclynk
la source