¿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 ?


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


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

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


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

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 .


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

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.


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:


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

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.


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/


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


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

no hay script predeterminado en la web. :(
— M al


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
  }
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.