Come faccio a trasformare un oggetto C # in una stringa JSON in .NET?


944

Ho lezioni come queste:

class MyDate
{
    int year, month, day;
}

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

E vorrei trasformare un Ladoggetto in una stringa JSON in questo modo:

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

(senza formattazione). Ho trovato questo link , ma utilizza uno spazio dei nomi che non è in .NET 4 . Ho anche sentito parlare di JSON.NET , ma al momento il loro sito sembra non funzionare e non mi piace usare file DLL esterni.

Esistono altre opzioni oltre alla creazione manuale di un writer di stringhe JSON ?


2
JSON.net può essere caricato qui Un'altra soluzione più rapida (come si suol dire - non l'ho provata da sola) è ServiceStack. Testo Non consiglierei di eseguire il rollup del proprio parser JSON. Probabilmente sarà più lento e più soggetto a errori o dovrai investire molto tempo.
Zebi,

sì. C # ha un tipo chiamato JavaScriptSerializer
Glenn Ferrie,


2
Hm .. per quanto posso vedere dovresti essere in grado di usare: msdn.microsoft.com/en-us/library/… Che è anche in .Net 4.0 secondo la pagina MSDN. Dovresti essere in grado di utilizzare il metodo Serialize (Object obj): msdn.microsoft.com/en-us/library/bb292287.aspx Mi sto perdendo qualcosa qui? Btw. il tuo link sembra essere un codice e non un link
Holger,

Per non parlare del fatto che non ha dipendenze dagli spazi dei nomi System.Web.Xyz ...
Dave Jellison

Risposte:


899

È possibile utilizzare la JavaScriptSerializerclasse (aggiungere riferimento a System.Web.Extensions):

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

Un esempio completo:

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);
    }
}

95
Tieni presente che Microsoft suggerisce di utilizzare JSON.net invece di questa soluzione. Penso che questa risposta sia diventata inappropriata. Dai un'occhiata alla risposta di Willsteel. Fonte: https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx .
rzelek,

9
@DarinDimitrov dovresti considerare di aggiungere un suggerimento su JSON.net. Microsoft lo consiglia su JavascriptSerializer: msdn.microsoft.com/en-us/library/… Puoi anche aggiungere un suggerimento a msdn.microsoft.com/en-us/library/… che è l'approccio incluso nel framework
Mafii

qui è lo strumento online per convertire il tuo classesin jsonformato, la speranza aiuta qualcuno.
Shaijut,

6
Perché Microsoft consiglierebbe una soluzione di terzi rispetto alla propria? Anche la loro formulazione è molto strana: "Json.NET dovrebbe essere usato per la serializzazione e la deserializzazione. Offre funzionalità di serializzazione e deserializzazione per le applicazioni abilitate per AJAX."
Protettore uno il

1
Solo un avvertimento, per fare riferimento System.Web.Extensions, è necessario disporre ASP.NET AJAX 1.0o ASP.NET 3.5installato sul sistema. Si prega di vedere questo stackoverflow.com/questions/7723489/...
Sisir

1056

Dal momento che tutti noi amiamo i liner

... questo dipende dal pacchetto NuGet Newtonsoft, che è popolare e migliore del serializzatore predefinito.

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

Documentazione: serializzazione e deserializzazione di JSON


134
Il serializzatore Newtonsoft è molto più veloce e personalizzabile rispetto a quello incorporato. Consiglio vivamente di usarlo. Grazie per la risposta @willsteel
Andrei,

8
@JosefPfleger il prezzo è per JSON.NET Schema, non JSON.NET il serializzatore normale, che è MIT
David Cumps

1
I miei test hanno dimostrato che Newtonsoft è più lento della classe JavaScriptSerializer. (.NET 4.5.2)
nemke,

31
Se leggi la documentazione MSDN per JavaScriptSerializer , si dice che usa JSON.net.
dsghi,

3
@JosefPfleger Newtionsoft JSON.net è concesso in licenza MIT ... è possibile apportare modifiche e rivenderlo come desiderato. La loro pagina dei prezzi riguarda il supporto tecnico commerciale e alcuni validatori di schemi che hanno.
cb88,

95

Usa la libreria Json.Net , puoi scaricarla da Nuget Packet Manager.

Serializzazione su 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);

Deserializzare all'oggetto:

var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<Lad>(jsonString );

57

Utilizzare la DataContractJsonSerializerclasse: MSDN1 , MSDN2 .

Il mio esempio: QUI .

Può anche deserializzare in modo sicuro oggetti da una stringa JSON, a differenza JavaScriptSerializer. Ma personalmente preferisco ancora Json.NET .


1
Ancora non vedo alcun esempio su quella pagina , ma qui ce ne sono alcuni su MSDN e altrove -> l'ultimo utilizza i metodi di estensione per ottenere una riga.
Cristian Diaconescu,

Oh, ho perso il secondo collegamento MSDN :)
Cristian Diaconescu il

2
Non serializza le classi semplici. L'errore riportava "Considerare di contrassegnarlo con l'attributo DataContractAttribute e contrassegnare tutti i suoi membri che si desidera serializzare con l'attributo DataMemberAttribute. Se il tipo è una raccolta, considerare di contrassegnarlo con l'attributo CollectionDataContractAttribute."
Michael Freidgeim,

@MichaelFreidgeim Esatto, devi contrassegnare le proprietà nella classe che vuoi serializzare con gli attributi. DataContractAttribute DataMemberAttribute
Edgar

1
@MichaelFreidgeim Che è meglio dipende dai requisiti. Gli attributi consentono di configurare la modalità di serializzazione della proprietà.
Edgar,

24

È possibile ottenere ciò utilizzando Newtonsoft.json. Installa Newtonsoft.json da NuGet. E poi:

using Newtonsoft.Json;

var jsonString = JsonConvert.SerializeObject(obj);

22

Wooou! Davvero meglio usando un framework JSON :)

Ecco il mio esempio usando 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
        }
    }
}

Il 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();
        }
    }
}

Il risultato:

{
  "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
    }
  ]
}

Ora implementerò il metodo di costruzione che riceverà una stringa JSON e popolerà i campi della classe.


1
Buon post, questo è il modo più attuale per farlo.
Matteo,

20

Un nuovo serializzatore JSON è disponibile nello System.Text.Jsonspazio dei nomi. È incluso nel framework condiviso .NET Core 3.0 ed è in un pacchetto NuGet per progetti destinati a .NET Standard o .NET Framework o .NET Core 2.x.

Codice di esempio:

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);
    }
}

In questo esempio le classi da serializzare hanno proprietà anziché campi; ilSystem.Text.Json serializzatore attualmente non serializza i campi.

Documentazione:


9

Se non sono molto grandi, quale potrebbe essere il tuo caso esportarlo come JSON.

Anche questo lo rende portatile su tutte le piattaforme.

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);
}

8

Se ti trovi in ​​un controller Web ASP.NET MVC è semplice come:

string ladAsJson = Json(Lad);

Non riesco a credere che nessuno lo abbia menzionato.


1
Viene visualizzato un errore per non essere in grado di trasmettere jsonresult alla stringa.
csga5000,

Si compilerà con la digitazione implicita: var ladAsJson = Json (Lad).
Ewomack,

3

Vorrei votare per il serializzatore JSON di ServiceStack:

using ServiceStack.Text

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

È anche il serializzatore JSON più veloce disponibile per .NET: http://www.servicestack.net/benchmarks/


4
Quelli sono benchmark molto vecchi lì. Ho appena testato tutte e tre le versioni attuali di Newtonsoft, ServiceStack e JavaScriptSerializer e attualmente Newtonsoft è il più veloce. Comunque lo fanno tutti abbastanza in fretta.
Michael Logutov,

1
ServiceStack non sembra essere gratuito.
Joelnet,

@joelnet ora è il caso, ma era gratuito quando rispondevo alla domanda. Tuttavia è gratuito per i siti di piccole dimensioni e lo sto ancora usando anche se è a pagamento, è un framework eccezionale.
James,

Alcuni benchmark qui, anche se non c'è per la serializzazione a sé stante: docs.servicestack.net/real-world-performance
JohnLBevan,

3

Utilizzare il codice seguente per convertire XML in JSON.

var json = new JavaScriptSerializer().Serialize(obj);

3

Utilizzare questi strumenti per generare una classe C #, quindi utilizzare questo codice per serializzare l'oggetto:

 var json = new JavaScriptSerializer().Serialize(obj);

3

È facile come questo (funziona anche con oggetti dinamici (tipo oggetto)):

string json = new
System.Web.Script.Serialization.JavaScriptSerializer().Serialize(MYOBJECT);

non esiste uno script predefinito nel Web. :(
M

Siete alla ricerca di questo: msdn.microsoft.com/en-us/library/...
MarzSocks

Ci ho provato ma no. Script Immagino che dovrei aggiungerlo come riferimento. Quindi grazie mille
M al

0

Serializer

 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);
        }
}

Oggetto

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;
    }
}

Implementazione

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

Produzione

{
  "AppSettings": {
    "DebugMode": false
  }
}
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.