Как превратить объект C # в строку JSON в .NET?


945

У меня есть такие классы:

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. Похоже, что ваша ссылка представляет собой некоторый код, а не ссылку
Holger

Не говоря уже о том, что он не зависит от пространств имен System.Web.Xyz ...
Дейв Джеллисон

Ответы:


900

Вы можете использовать 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/…, который является подходом, включенным в фреймворк
Mafii

здесь это интерактивный инструмент для преобразования вашего classesв jsonформат, надеюсь , поможет кому - то.
Шайют

6
Почему Microsoft рекомендует сторонние решения вместо своих? Их формулировка также очень странная: «В Json.NET следует использовать сериализацию и десериализацию. Предоставляет функциональность сериализации и десериализации для приложений с поддержкой AJAX».
Один защитник

1
Просто хедз-ап, для ссылки System.Web.Extensions, вы должны иметь ASP.NET AJAX 1.0или ASP.NET 3.5установить в вашей системе. Пожалуйста, смотрите этот stackoverflow.com/questions/7723489/…
Сисир

1058

Так как мы все любим однострочники

... это зависит от пакета Newtonsoft NuGet, который популярен и лучше, чем стандартный сериализатор.

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

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


134
Сериализатор Newtonsoft намного быстрее и более настраиваемый, чем встроенный. Настоятельно рекомендуем его использовать. Спасибо за ответ @willsteel
Андрей

8
@JosefPfleger цена для JSON.NET Schema, а не JSON.NET для обычного сериализатора, который является MIT
Дэвид Кампс

1
Мои тесты показали, что Newtonsoft работает медленнее, чем класс JavaScriptSerializer. (.NET 4.5.2)
немке

31
Если вы читаете документацию MSDN для JavaScriptSerializer , он говорит, что использует JSON.net.
DSHI

3
@JosefPfleger Newtionsoft JSON.net имеет лицензию MIT ... вы можете вносить изменения и перепродавать его по своему желанию. На их странице с ценами рассказывается о коммерческой технической поддержке и об их валидаторе схемы.
cb88

96

Используйте библиотеку Json.Net , вы можете скачать ее из Nuget Packet Manager.

Сериализация для 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);

Десериализация в объект:

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

Wooou! Действительно лучше, используя JSON Framework :)

Вот мой пример использования 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 является самой быстрой. То они все делают довольно быстро.
Михаил Логутов

1
ServiceStack не является бесплатным.
joelnet

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

Некоторые тесты здесь, хотя и не для сериализации сами по себе: docs.servicestack.net/real-world-performance
JohnLBevan

3

Используйте приведенный ниже код для преобразования XML в JSON.

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


3

Это так просто (это работает и для динамических объектов (тип object)):

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

в сети нет скрипта по умолчанию. :(
М в


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

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

объект

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.