Como transformar um objeto C # em uma string JSON no .NET?

944

Eu tenho aulas como estas:

class MyDate
{
    int year, month, day;
}

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

E eu gostaria de transformar um Ladobjeto em uma string JSON assim:

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

(sem a formatação). Encontrei este link , mas ele usa um espaço para nome que não está no .NET 4 . Eu também ouvi sobre o JSON.NET , mas o site deles parece estar inativo no momento e não estou interessado em usar arquivos DLL externos.

Existem outras opções além de criar manualmente um gravador de string JSON ?

Hui
fonte
2
O JSON.net pode ser carregado aqui. Outra solução mais rápida (como eles dizem - eu não testei) é o ServiceStack.Text. Eu não recomendaria rolar o seu próprio analisador JSON. Provavelmente será mais lento e propenso a erros ou você precisará investir muito tempo.
Zebi
sim. C # tem um tipo chamado JavaScriptSerializer
Glenn Ferrie
possível duplicação de Generics / JSON JavaScriptSerializer C #
Filip Ekberg
2
Hm .. até onde posso ver, você deve poder usar: msdn.microsoft.com/en-us/library/…, que também está no .Net 4.0, de acordo com a página do MSDN. Você deve conseguir usar o método Serialize (Object obj): msdn.microsoft.com/en-us/library/bb292287.aspx Estou faltando alguma coisa aqui? Btw. você link parece ser um algum código e não um link
Holger
Para não falar que não tem dependências sobre os namespaces System.Web.Xyz ...
Dave Jellison

Respostas:

899

Você pode usar a JavaScriptSerializerclasse (adicione referência a System.Web.Extensions):

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

Um exemplo 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
fonte
95
Lembre-se de que a Microsoft sugere o uso do JSON.net em vez desta solução. Eu acho que essa resposta se tornou inadequada. Dê uma olhada na resposta da willsteel. Fonte: https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx .
#
9
@DarinDimitrov, você deve considerar adicionar uma dica sobre JSON.net. A Microsoft recomenda o JavascriptSerializer: msdn.microsoft.com/en-us/library/… Você também pode adicionar uma dica para msdn.microsoft.com/en-us/library/…, que é a abordagem incluída na estrutura
Mafii
aqui é ferramenta online para converter seu classespara jsonformato, esperança ajuda a alguém.
precisa saber é
6
Por que a Microsoft recomendaria uma solução de terceiros por conta própria? Suas palavras também são muito estranhas: "O Json.NET deve ser usado para serialização e desserialização. Fornece funcionalidade de serialização e desserialização para aplicativos habilitados para AJAX".
Protector one
1
Apenas um aviso, para referência System.Web.Extensions, você deve ter ASP.NET AJAX 1.0ou ASP.NET 3.5instalar no seu sistema. Por favor, veja este stackoverflow.com/questions/7723489/…
Sisir 15/10/18
1056

Desde que todos nós amamos one-liners

... este depende do pacote Newtonsoft NuGet, que é popular e melhor que o serializador padrão.

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

Documentation: JSON serializando e desserializando

mschmoock
fonte
134
O serializador de Newtonsoft é bem mais rápido e personalizável do que incorporado. Recomenda-se usá-lo. Obrigado pela resposta @willsteel
Andrei
8
@JosefPfleger o preço é para JSON.NET Schema, não JSON.NET o serializador regular, que é MIT
David Cumps
1
Meus testes mostraram que a Newtonsoft é mais lenta que a classe JavaScriptSerializer. (.NET 4.5.2)
nemke 28/09
31
Se você ler a documentação do MSDN para JavaScriptSerializer , é simples dizer que use JSON.net.
dsghi
3
@JosefPfleger O Newtionsoft JSON.net é licenciado pelo MIT ... você pode fazer modificações e revendê-lo como desejar. Sua página de preços é sobre suporte técnico comercial e algum validador de esquema que eles possuem.
precisa saber é o seguinte
95

Use Json.Net biblioteca , você pode baixá-lo no Nuget Packet Manager.

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

Desserializando para Objeto:

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

Use a DataContractJsonSerializerclasse: MSDN1 , MSDN2 .

Meu exemplo: AQUI .

Ele também pode desserializar objetos com segurança de uma sequência JSON, ao contrário JavaScriptSerializer. Mas pessoalmente ainda prefiro o Json.NET .

Edgar
fonte
1
Ainda não vemos exemplos nessa página , mas aqui estão alguns no MSDN e em outros lugares -> o último usa métodos de extensão para obter one-liners.
Cristian Diaconescu
Oh, eu perdi o link 2 MSDN :)
Cristian Diaconescu
2
Não serializa classes simples. O erro relatado "Considere marcar com o atributo DataContractAttribute e marcar todos os seus membros que você deseja serializar com o atributo DataMemberAttribute. Se o tipo for uma coleção, considere marcá-lo com o CollectionDataContractAttribute."
22616 Michael Freidgeim
@MichaelFreidgeim Isso mesmo, você precisa marcar propriedades na classe que deseja serializar com atributos. DataContractAttribute DataMemberAttribute
Edgar
1
@MichaelFreidgeim Qual é o melhor depende dos requisitos. Os atributos permitem configurar como a propriedade é serializada.
Edgar
24

Você pode conseguir isso usando o Newtonsoft.json. Instale o Newtonsoft.json do NuGet. E depois:

using Newtonsoft.Json;

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

Wooou! Realmente melhor usando uma estrutura JSON :)

Aqui está o meu exemplo usando o 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
        }
    }
}

O teste:

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

O 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
    }
  ]
}

Agora vou implementar o método construtor que recebe uma string JSON e preenche os campos da classe.

Jean J. Michel
fonte
1
Bom post, esta é a maneira mais atual de fazer isso.
MatthewD
20

Um novo serializador JSON está disponível no System.Text.Jsonespaço para nome. Ele está incluído na estrutura compartilhada do .NET Core 3.0 e está em um pacote NuGet para projetos direcionados ao .NET Standard ou .NET Framework ou .NET Core 2.x.

Código de exemplo:

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

Neste exemplo, as classes a serem serializadas têm propriedades em vez de campos; aSystem.Text.Json serializador atualmente não serializa campos.

Documentação:

tdykstra
fonte
9

Se eles não forem muito grandes, provavelmente o seu caso será exportado como JSON.

Também isso o torna portátil entre todas as 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);
}
user8426627
fonte
8

Se você estiver em um controlador da Web ASP.NET MVC, é tão simples quanto:

string ladAsJson = Json(Lad);

Não posso acreditar que ninguém tenha mencionado isso.

micahhoover
fonte
1
Eu recebo um erro por não conseguir converter jsonresult em string.
precisa saber é o seguinte
Ele será compilado com a digitação implícita: var ladAsJson = Json (Lad).
ewomack
3

Eu votaria no JSON Serializer do ServiceStack:

using ServiceStack.Text

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

É também o serializador JSON mais rápido disponível para o .NET: http://www.servicestack.net/benchmarks/

James
fonte
4
Esses são benchmarks muito antigos lá. Acabei de testar todas as três versões atuais do Newtonsoft, ServiceStack e JavaScriptSerializer e atualmente o Newtonsoft é o mais rápido. Eles todos fazem muito rápido.
Michael Logutov
1
O ServiceStack não parece ser gratuito.
Joelnet
@joelnet agora é esse o caso, mas estava livre ao responder à pergunta. No entanto, é gratuito para sites pequenos, e ainda o estou usando, embora seja pago, é uma estrutura excelente.
19413 James
Alguns benchmarks aqui, embora não exista para a serialização por si só: docs.servicestack.net/real-world-performance
JohnLBevan
3

Use o código abaixo para converter XML em JSON.

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

Use estas ferramentas para gerar uma classe C # e, em seguida, use este código para serializar seu objeto:

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

É tão fácil quanto isso (funciona também para objetos dinâmicos (tipo objeto)):

string json = new
System.Web.Script.Serialization.JavaScriptSerializer().Serialize(MYOBJECT);
MarzSocks
fonte
não há script padrão na web. :(
M em
Você está procurando: msdn.microsoft.com/en-us/library/…
MarzSocks
Eu meio que tentei isso, mas não. Script, acho que devo adicioná-lo como referência. Então, muito obrigado
M em
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);
        }
}

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

Implementação

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

Resultado

{
  "AppSettings": {
    "DebugMode": false
  }
}
dynamiclynk
fonte