¿Cómo convierto un objeto C # en una cadena JSON en .NET?

944

Tengo clases como estas:

class MyDate
{
    int year, month, day;
}

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

Y me gustaría convertir un Ladobjeto en una cadena JSON como esta:

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

(sin el formato). Encontré este enlace , pero usa un espacio de nombres que no está en .NET 4 . También escuché sobre JSON.NET , pero su sitio parece estar inactivo en este momento, y no estoy interesado en usar archivos DLL externos.

¿Hay otras opciones además de crear manualmente un escritor de cadenas JSON ?

Hui
fuente
2
JSON.net se puede cargar aquí. Otra solución más rápida (como dicen, no lo probé yo mismo) es ServiceStack . Texto No recomendaría lanzar su propio analizador JSON. Es probable que sea más lento y más propenso a errores o que tenga que invertir mucho tiempo.
Zebi
si. C # tiene un tipo llamado JavaScriptSerializer
Glenn Ferrie
posible duplicado de Generics / JSON JavaScriptSerializer C #
Filip Ekberg
2
Hm ... por lo que puedo ver, debería poder usar: msdn.microsoft.com/en-us/library/… que también está en .Net 4.0 de acuerdo con la página de MSDN. Debería poder utilizar el método Serialize (Object obj): msdn.microsoft.com/en-us/library/bb292287.aspx ¿Me estoy perdiendo algo aquí? Por cierto. su enlace parece ser un código y no un enlace
Holger
Sin mencionar que no tiene dependencias en los espacios de nombres System.Web.Xyz ...
Dave Jellison

Respuestas:

899

Puede usar la JavaScriptSerializerclase (agregar referencia a System.Web.Extensions):

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

Un ejemplo 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);
    }
}
Darin Dimitrov
fuente
95
Tenga en cuenta que Microsoft sugiere utilizar JSON.net en lugar de esta solución. Creo que esta respuesta se volvió inapropiada. Echa un vistazo a la respuesta de willsteel. Fuente: https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx .
rzelek
99
@DarinDimitrov, debería considerar agregar una pista sobre JSON.net. Microsoft lo recomienda sobre JavascriptSerializer: msdn.microsoft.com/en-us/library/… También puede agregar una pista a msdn.microsoft.com/en-us/library/…, que es el enfoque de marco incluido
Mafii
aquí es la herramienta en línea para convertir su classesa jsonformato, esperanza ayuda a alguien.
shaijut
66
¿Por qué Microsoft recomendaría una solución de terceros sobre la suya? Su redacción también es muy extraña: "Json.NET debe usarse serialización y deserialización. Proporciona funcionalidades de serialización y deserialización para aplicaciones habilitadas para AJAX".
Protector uno
1
Solo un aviso, para hacer referencia System.Web.Extensions, debe tener ASP.NET AJAX 1.0o ASP.NET 3.5instalar en su sistema. Consulte este stackoverflow.com/questions/7723489/…
Sisir el
1056

Como todos amamos las frases sencillas

... este depende del paquete Newtonsoft NuGet, que es popular y mejor que el serializador predeterminado.

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

Documentación: serialización y deserialización de JSON

mschmoock
fuente
134
El serializador Newtonsoft es mucho más rápido y más personalizable que incorporado. Se recomienda utilizarlo. Gracias por la respuesta @willsteel
Andrei
8
@JosefPfleger el precio es para el esquema JSON.NET, no JSON.NET el serializador regular, que es MIT
David Cumps
1
Mi prueba mostró que Newtonsoft es más lento que la clase JavaScriptSerializer. (.NET 4.5.2)
nemke
31
Si lees la documentación de MSDN para JavaScriptSerializer , dice que usa JSON.net.
dsghi
3
@JosefPfleger Newtionsoft JSON.net tiene licencia MIT ... puede hacer modificaciones y revenderlo como desee. Su página de precios trata sobre soporte técnico comercial y algunos validadores de esquemas que tienen.
cb88
95

Utilice la biblioteca Json.Net , puede descargarla desde Nuget Packet Manager.

Serializando a 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);

Deserialización al objeto:

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

Use la DataContractJsonSerializerclase: MSDN1 , MSDN2 .

Mi ejemplo: AQUÍ .

También puede deserializar de forma segura los objetos de una cadena JSON, a diferencia JavaScriptSerializer. Pero personalmente todavía prefiero Json.NET .

Edgar
fuente
1
Todavía no veo ningún ejemplo en esa página , pero aquí hay algunos en MSDN y en otros lugares -> el último usa métodos de extensión para lograr frases ingeniosas.
Cristian Diaconescu
Oh, me perdí el segundo enlace de MSDN :)
Cristian Diaconescu
2
No serializa clases simples. El error informó "Considere marcarlo con el atributo DataContractAttribute y marcar todos los miembros que desea serializar con el atributo DataMemberAttribute. Si el tipo es una colección, considere marcarlo con el CollectionDataContractAttribute".
Michael Freidgeim
@MichaelFreidgeim Así es, debe marcar las propiedades en la clase que desea serializar con atributos. DataContractAttribute DataMemberAttribute
Edgar
1
@MichaelFreidgeim Lo que es mejor depende de los requisitos. Los atributos le permiten configurar cómo se serializa la propiedad.
Edgar
24

Puede lograr esto usando Newtonsoft.json. Instale Newtonsoft.json desde NuGet. Y entonces:

using Newtonsoft.Json;

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

Wooou! Realmente mejor usando un marco JSON :)

Aquí está mi ejemplo 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
        }
    }
}

La prueba:

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

El resultado:

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

Ahora implementaré el método constructor que recibirá una cadena JSON y completará los campos de la clase.

Jean J. Michel
fuente
1
Buena publicación, esta es la forma más actual de hacerlo.
MatthewD
20

Un nuevo serializador JSON está disponible en el System.Text.Jsonespacio de nombres. Está incluido en el marco compartido .NET Core 3.0 y está en un paquete NuGet para proyectos que apuntan a .NET Standard o .NET Framework o .NET Core 2.x.

Código de ejemplo:

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

En este ejemplo, las clases a serializar tienen propiedades en lugar de campos; laSystem.Text.Json serializador actualmente no serializa campos.

Documentación:

tdykstra
fuente
9

Si no son muy grandes, ¿cuál es su caso? Exportarlo como JSON.

Además, esto lo hace portátil entre todas las plataformas.

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);
}
usuario8426627
fuente
8

Si está en un controlador web ASP.NET MVC, es tan simple como:

string ladAsJson = Json(Lad);

No puedo creer que nadie haya mencionado esto.

micahhoover
fuente
1
Me sale un error acerca de no poder convertir jsonresult a la cadena.
csga5000
Se compilará con una tipificación implícita: var ladAsJson = Json (Lad).
ewomack el
3

Yo votaría por el serializador JSON de ServiceStack:

using ServiceStack.Text

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

También es el serializador JSON más rápido disponible para .NET: http://www.servicestack.net/benchmarks/

James
fuente
44
Esos son puntos de referencia muy antiguos allí. Acabo de probar las tres versiones actuales de Newtonsoft, ServiceStack y JavaScriptSerializer y actualmente Newtonsoft es la más rápida. Aunque todos lo hacen bastante rápido.
Michael Logutov
1
ServiceStack no parece ser gratuito.
joelnet
@joelnet, este es el caso, pero era gratis al responder la pregunta. Sin embargo, es gratuito para sitios pequeños, y todavía lo estoy utilizando a pesar de que es de pago, es un marco excelente.
James
Algunos puntos de referencia aquí, aunque no hay para la serialización por sí solo: docs.servicestack.net/real-world-performance
JohnLBevan
3

Use el siguiente código para convertir XML a JSON.

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

Use estas herramientas para generar una clase C # y luego use este código para serializar su objeto:

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

Es tan fácil como esto (también funciona para objetos dinámicos (tipo de objeto)):

string json = new
System.Web.Script.Serialization.JavaScriptSerializer().Serialize(MYOBJECT);
MarzSocks
fuente
no hay script predeterminado en la web. :(
M al
Estás buscando esto: msdn.microsoft.com/en-us/library/…
MarzSocks
Lo intenté, pero no. Script, supongo que debería agregarlo como referencia. Así que muchas gracias
M al
0

Serializador

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

Objeto

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

Implementación

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

Salida

{
  "AppSettings": {
    "DebugMode": false
  }
}
Dynamiclynk
fuente