Серіалізація списку до JSON


182

У мене є об'єктна модель, яка виглядає приблизно так:

public MyObjectInJson
{
   public long ObjectID {get;set;}
   public string ObjectInJson {get;set;}
}

Властивість ObjectInJson- це вже серіалізована версія об'єкта, що містить вкладені списки. На даний момент я серіалізую такий список MyObjectInJsonвручну:

StringBuilder TheListBuilder = new StringBuilder();

TheListBuilder.Append("[");
int TheCounter = 0;

foreach (MyObjectInJson TheObject in TheList)
{
  TheCounter++;
  TheListBuilder.Append(TheObject.ObjectInJson);

  if (TheCounter != TheList.Count())
  {
    TheListBuilder.Append(",");
  }
}
TheListBuilder.Append("]");

return TheListBuilder.ToString();

Цікаво, чи зможу я замінити такий небезпечний код JavascriptSerializerі отримати ті ж результати. Як би я це зробив?

Дякую.


Зауважте, що у проекті WPF вам потрібно додати посилання System.Web.Extensionsна використання System.Web.Script.Serialization: stackoverflow.com/a/18746092/1599699 stackoverflow.com/a/19299695/1599699
Ендрю

Відповіді:


338

Якщо використовується .Net Core 3.0 або новішої версії;

За замовчуванням використовується вбудована в System.Text.Jsonпарсер реалізація.

напр

using System.Text.Json;

var json = JsonSerializer.Serialize(aList);

Крім того, доступні інші, менш мейнстрим-параметри, такі як аналізатор Utf8Json та Jil : Вони можуть забезпечити чудову ефективність , якщо вам це справді потрібно, але вам потрібно буде встановити відповідні пакети.

Якщо застрягли користування .Net Core 2.2 або новішої версії;

За замовчуванням використовувати Newtonsoft JSON.Net як ваш перший вибір JSON Parser.

напр

using Newtonsoft.Json;

var json = JsonConvert.SerializeObject(aList);

Вам може знадобитися спочатку встановити пакет.

PM> Install-Package Newtonsoft.Json

Для отримання більш детальної інформації див. Та підтвердимо відповідь, яка є джерелом цієї інформації .

Для довідки це була оригінальна відповідь багато років тому;

// you need to reference System.Web.Extensions

using System.Web.Script.Serialization;

var jsonSerialiser = new JavaScriptSerializer();
var json = jsonSerialiser.Serialize(aList);

1
ах добре, це ТАКОЖ серіалізує списки об'єктів, а не лише самі об'єкти. Дякую.
шаленство

не люблять циклічних відносин, але це не проблема
Джодрелл

13
Зауважте, що цей простір імен хитро затягнутий у System.Web.Extensions. Як тільки ви додасте це в якості довідки, рішення працює чудово!
Вісім-бітний гуру

1
Я бачу вашу відредаговану відповідь і дуже хочу, щоб я мав оновлений приклад.
Ділан Брамс

1
@ IamNumber5 вже вказано в іншій відповіді. Я все одно продовжив свою відповідь.
Джодрелл

111

Ви також можете використовувати Json.NET. Просто завантажте його на сторінку http://james.newtonking.com/pages/json-net.aspx , витягніть стиснутий файл і додайте його як орієнтир.

Потім просто серіалізуйте список (або будь-який об’єкт, який ви хочете) із наступним:

using Newtonsoft.Json;

string json = JsonConvert.SerializeObject(listTop10);

Оновлення: ви також можете додати його до свого проекту через диспетчер пакунків NuGet (Інструменти -> Менеджер пакунків NuGet -> Консоль менеджера пакунків):

PM> Install-Package Newtonsoft.Json

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


12

Існує два поширених способи зробити це за допомогою вбудованих серіалізаторів JSON:

  1. JavaScriptSerializer

    var serializer = new JavaScriptSerializer();
    return serializer.Serialize(TheList);
  2. DataContractJsonSerializer

    var serializer = new DataContractJsonSerializer(TheList.GetType());
    using (var stream = new MemoryStream())
    {
        serializer.WriteObject(stream, TheList);
        using (var sr = new StreamReader(stream))
        {
            return sr.ReadToEnd();
        }
    }

    Зауважте, що цей параметр вимагає визначення договору даних для вашого класу:

    [DataContract]
    public class MyObjectInJson
    {
       [DataMember]
       public long ObjectID {get;set;}
       [DataMember]
       public string ObjectInJson {get;set;}
    }

5
public static string JSONSerialize<T>(T obj)
        {
            string retVal = String.Empty;
            using (MemoryStream ms = new MemoryStream())
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
                serializer.WriteObject(ms, obj);
                var byteArray = ms.ToArray();
                retVal = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
            }
            return retVal;
        }

4

.NET вже підтримує базову серіалізацію Json через простір імен System.Runtime.Serialization.Json та клас DataContractJsonSerializer з версії 3.5. Як випливає з назви, DataContractJsonSerializer враховує будь-які анотації даних, які ви додаєте до своїх об'єктів, щоб створити остаточний вихід Json.

Це може бути корисно, якщо у вас вже є анотовані класи даних, які ви хочете серіалізувати Json у потік, як описано у розділі Як: Серіалізувати та десеріалізувати дані JSON . Є обмеження, але це досить добре і досить швидко, якщо у вас є основні потреби і не хочете додавати ще один бібліотеку до свого проекту.

Наступний код серіалізує список до вихідного потоку консолі. Як ви бачите, він трохи більш багатослівний, ніж Json.NET, і не є безпечним для типу (тобто немає дженериків)

        var list = new List<string> {"a", "b", "c", "d"};

        using(var output = Console.OpenStandardOutput())                
        {                
            var writer = new DataContractJsonSerializer(typeof (List<string>));
            writer.WriteObject(output,list);
        }

З іншого боку, Json.NET забезпечує набагато кращий контроль над тим, як ви генеруєте Json. Це стане дуже зручним, коли вам доведеться зіставляти зручні для Javascript імена імен до .NET-класів, форматувати дати в json тощо.

Інший варіант - ServiceStack.Text , частина стеку ServicStack ..., яка забезпечує набір дуже швидких серіалізаторів для Json, JSV та CSV.


0

спираючись на відповідь з іншої публікації .. Я придумав більш загальний спосіб скласти список, використовуючи динамічне пошук за допомогою Json.NET версії 12.x

using Newtonsoft.Json;

static class JsonObj
{
    /// <summary>
    /// Deserializes a json file into an object list
    /// Author: Joseph Poirier 2/26/2019
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="fileName"></param>
    /// <returns></returns>
    public static List<T> DeSerializeObject<T>(string fileName)
    {
        List<T> objectOut = new List<T>();

        if (string.IsNullOrEmpty(fileName)) { return objectOut; }

        try
        {
            // reading in full file as text
            string ss = File.ReadAllText(fileName);

            // went with <dynamic> over <T> or <List<T>> to avoid error..
            //  unexpected character at line 1 column 2
            var output = JsonConvert.DeserializeObject<dynamic>(ss);

            foreach (var Record in output)
            {
                foreach (T data in Record)
                {
                    objectOut.Add(data);
                }
            }
        }
        catch (Exception ex)
        {
            //Log exception here
            Console.Write(ex.Message);
        }

        return objectOut;
    }
}

заклик до обробки

{
        string fname = "../../Names.json"; // <- your json file path

        // for alternate types replace string with custom class below
        List<string> jsonFile = JsonObj.DeSerializeObject<string>(fname);
}

або цей заклик обробити

{
        string fname = "../../Names.json"; // <- your json file path

        // for alternate types replace string with custom class below
        List<string> jsonFile = new List<string>();
        jsonFile.AddRange(JsonObj.DeSerializeObject<string>(fname));
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.