Як перетворити об'єкт C # в рядок JSON в .NET?


944

У мене такі заняття:

class MyDate
{
    int year, month, day;
}

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

І я хотів би перетворити Ladоб'єкт у рядок JSON таким чином:

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

(без форматування). Я знайшов це посилання , але він використовує простір імен, який відсутній у .NET 4 . Я також чув про JSON.NET , але, схоже , їх сайт наразі не працює, і я не прагну використовувати зовнішні файли DLL.

Чи є інші варіанти, крім створення вручну записувача струнів JSON ?


2
JSON.net можна завантажити тут Іншим і швидше (як вони кажуть - я не перевіряв це сам) рішення ServiceStack.Text я не рекомендував би додати власні JSON парсер. Це, швидше за все, буде повільніше і більше схильних до помилок або вам доведеться вкладати багато часу.
Зебі

так. C # має тип під назвою JavaScriptSerializer
Гленн Феррі


2
Гм .. наскільки я бачу, ви повинні мати можливість використовувати: msdn.microsoft.com/en-us/library/… Що також знаходиться у. Net 4.0 відповідно до сторінки MSDN. Ви повинні мати можливість використовувати метод Serialize (Object obj): msdn.microsoft.com/en-us/library/bb292287.aspx Я тут щось пропускаю? Btw. у вас посилання здається, що це якийсь код, а не посилання
Холгер

Не кажучи вже про те, що він не має залежності від просторів імен System.Web.Xyz ...
Дейв Джеллісон

Відповіді:


898

Ви можете використовувати JavaScriptSerializerклас (додати посилання на System.Web.Extensions):

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

Повний приклад:

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
Майте на увазі, що Microsoft пропонує використовувати JSON.net замість цього рішення. Я думаю, що ця відповідь стала недоречною. Подивіться на відповідь Устістеля. Джерело: https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx .
rzelek

9
@DarinDimitrov, вам варто розглянути можливість додавання підказки про JSON.net. Microsoft рекомендує це через JavascriptSerializer: msdn.microsoft.com/en-us/library/… Ви також можете додати підказку до msdn.microsoft.com/en-us/library/…, що є
базовим

тут це інтерактивний інструмент для перетворення вашого classesв jsonформат, сподіваюся , допоможе кому - то.
shaijut

6
Чому Microsoft рекомендувала б рішення сторонніх розробників над власним? Їх формулювання також дуже дивне: "Json.NET слід використовувати серіалізацію та десеріалізацію. Забезпечує функціонування серіалізації та десеріалізації для додатків з підтримкою AJAX."
Захисник один

1
Для посилання System.Web.Extensionsви повинні мати ASP.NET AJAX 1.0або ASP.NET 3.5встановити їх у вашій системі. Будь ласка , дивіться цю stackoverflow.com/questions/7723489 / ...
Sisir

1054

Оскільки ми всі любимо однолінійки

... це залежить від пакету Newtonsoft NuGet, який популярний і кращий, ніж серіалізатор за замовчуванням.

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

Документація: Серіалізація та десеріалізація JSON


134
Серіалізатор Newtonsoft - це набагато швидше, і він може бути налаштований, а потім вбудований. Настійно рекомендую використовувати його. Дякую за відповідь @willsteel
Андрій

8
@JosefPfleger ціна призначена для схеми JSON.NET, а не JSON.NET - звичайного серіалізатора, який є MIT
David Cumps

1
Моє тестування показало, що Newtonsoft повільніше, ніж клас JavaScriptSerializer. (.NET 4.5.2)
nemke

31
Якщо ви читаєте документацію MSDN для JavaScriptSerializer , вона вирівнюється, використовуйте JSON.net.
dsghi

3
@JosefPfleger Newtionsoft JSON.net має ліцензію на MIT ... ви можете внести зміни та перепродати їх, як хотіли. Їх сторінка з цінами стосується комерційної технічної підтримки та деяких валідаторів схем.
cb88

95

Використовуйте бібліотеку Json.Net , ви можете завантажити її з Nuget Packet Manager.

Серіалізація до струни Json:

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

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

Десеріалізація об'єкта:

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

57

Використовуйте DataContractJsonSerializerклас: MSDN1 , MSDN2 .

Мій приклад: ТУТ .

Він також може безпечно десеріалізувати об'єкти з рядка JSON, на відміну від цього JavaScriptSerializer. Але особисто я все ж віддаю перевагу Json.NET .


1
Досі не бачу жодних прикладів на цій сторінці , але ось деякі на MSDN та інших місцях -> останній використовує методи розширення для досягнення однолінійки.
Крістіан Діаконеску

О, я пропустив 2-е посилання MSDN :)
Крістіан Діаконеску,

2
Це не серіалізує звичайні класи. Повідомляється про помилку "Подумайте про позначення його атрибутом DataContractAttribute та позначте всіх його членів, які ви хочете серіалізувати за допомогою атрибута DataMemberAttribute. Якщо тип - це колекція, розгляньте, як позначити його за допомогою CollectionDataContractAttribute."
Майкл Фрейджім

@MichaelFreidgeim Правильно, ви повинні позначити властивості в класі, який ви хочете серіалізувати за допомогою атрибутів. DataContractAttribute DataMemberAttribute
Едгар

1
@MichaelFreidgeim Що краще залежить від вимог. Атрибути дозволяють налаштувати спосіб серіалізації властивості.
Едгар

24

Ви можете досягти цього, використовуючи Newtonsoft.json. Встановіть Newtonsoft.json від NuGet. І потім:

using Newtonsoft.Json;

var jsonString = JsonConvert.SerializeObject(obj);

22

Ву! Дійсно краще, використовуючи рамку JSON :)

Ось мій приклад використання 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
        }
    }
}

Тест:

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

Результат:

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

Тепер я реалізую метод конструктора, який отримає рядок JSON і заповнить поля класу.


1
Добрий пост, це найсучасніший спосіб зробити це.
MatthewD

20

Новий серіалізатор JSON доступний у System.Text.Jsonпросторі імен. Він включений у загальну основу .NET Core 3.0 і є пакетом NuGet для проектів, орієнтованих на .NET Standard або .NET Framework або .NET Core 2.x.

Приклад коду:

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

У цьому прикладі класи, які підлягають серіалізації, мають властивості, а не поля; в System.Text.Jsonданий час серіалізатор не серіалізує поля.

Документація:


9

Якщо вони не дуже великі, то, ймовірно, ваш випадок експортує це як JSON.

Також це робить його портативним серед усіх платформ.

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

Якщо ви перебуваєте у веб-контролері ASP.NET MVC, це так само просто, як:

string ladAsJson = Json(Lad);

Не можу повірити, що про це ніхто не згадував.


1
У мене з’являється помилка про те, що я не можу передавати jsonresult на рядок.
csga5000

Він буде компілюватися з неявним набором тексту: var ladAsJson = Json (Lad).
ewomack

3

Я би голосував за серіалізатор JSON ServiceStack:

using ServiceStack.Text

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

Це також найшвидший серіалізатор JSON, доступний для .NET: http://www.servicestack.net/benchmarks/


4
Це дуже старі орієнтири. Я тільки перевірив усі три поточні версії Newtonsoft, ServiceStack та JavaScriptSerializer, і в даний час Newtonsoft є найшвидшим. Tho вони все роблять досить швидко.
Михайло Логутов

1
Схоже, ServiceStack не є безкоштовним.
joelnet

@joelnet це вже так, але він відповідав на запитання. Однак він безкоштовний для невеликих сайтів, і я все ще використовую його, хоча він і платить, це чудова рамка.
Джеймс

Деякі орієнтири тут, хоча не існує серіалізації самостійно: docs.servicestack.net/real-world-performance
JohnLBevan

3

Використовуйте наведений нижче код для перетворення XML в JSON.

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


3

Це так просто, як це (він працює і для динамічних об'єктів (тип об'єкта)):

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

в Інтернеті немає сценарію за замовчуванням. :(
M у


Я якось спробував це, але ні. Сценарій Я думаю, я повинен додати його як посилання. Тож велике спасибі
М

0

Серіалізатор

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

Об'єкт

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

Впровадження

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

Вихідні дані

{
  "AppSettings": {
    "DebugMode": false
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.